Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Работа с пользовательскими данными | Комментарии для статьи [RSS Feed]

#1 Июль 6, 2015 15:08:25

VansKiter
Зарегистрирован: 2015-05-13
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

Всем привет. Пытаюсь сделать комментарии для статей, но при вводе в форму и нажатии на кнопку Отправить комментарий открывается ссылка http://127.0.0.1:8000/articles/addcomment/1/ и комментарий не добавляется, хотя должен добавиться комментарий и открыться страница статьи на которую оставлен комментарий вида http://127.0.0.1:8000/articles/get/1/ .
urls.py:

url(r'^articles/addcomment/(?P<article_id>\d)/+$', 'article.views.addcomment'),
Сама форма в html странице:
<form action = '/articles/addcomment/{{ article.id }}/' method="post">
{% csrf_token %}
{{ form }}
<input type = 'submit' class = 'button' value="Добавить комментарий">
</form>
в models.py class:
class Comments(models.Model):
    class Meta:
        db_table = 'comments'
    text = models.TextField(verbose_name='Текст комметария')
    comments_article = models.ForeignKey(Article)
forms.py:
from django.forms import ModelForm
from article.models import Comments
class CommentForm(ModelForm):
    class Meta:
        model = Comments
        fields = '__all__'
        exclude = ['comments_article']
views.py
def addcomment(request, article_id):
    if request.POST:
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.comments_article = Article.objects.get(id=article_id)
            form.save()
    return redirect('/articles/get/%s/' % article_id)

Отредактировано VansKiter (Июль 6, 2015 15:10:41)

Офлайн

#2 Июль 6, 2015 19:03:32

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

1.

            comment = form.save(commit=False)
            comment.comments_article = Article.objects.get(id=article_id)
            form.save()
может всё-таки не form.save(), а comment.save() ?
2. Что за функция redirect, откуда она?
3. if request.POST:
Да ну нафиг, всегда было if request.method == “POST”



Офлайн

#3 Июль 7, 2015 05:11:18

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

FishHook
2. Что за функция redirect, откуда она?
я так понимаю это намек автору топика, что мол надо указывать импорт приводы фрагмент кода. Ну а вообще это django.shortcuts.redirect
FishHook
3. if request.POST:
Да ну нафиг, всегда было if request.method == “POST”
не совсем, тут если заранее известно что на этот запрос дожен быть послан POST запрос, то проверяется сразу содержание словаря. Если он пустой - то запрос не был отправлен.
Я кстати так и проверяю. М.б. даже такая конструкция:
if request.POST:
    ....
elif request.GET:
    ....
else:
    ....



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#4 Июль 7, 2015 05:58:10

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

JOHN_16
то проверяется сразу содержание словаря. Если он пустой - то запрос не был отправлен.
Не очень понимаю, как запрос попал в представление, если он не был отправлен.
Если реквест дошёл до вью, то он однозначно имеет тип из набора методов HTTP.
ИМХО тип запроса надо проверять явно, не столько потому что это облегчает понимание кода, сколько потому, что твой подход ведет к потенциальным трудноотлавливаемым багам. Например, ГЕТ вполне может быть не пустым при ПОСТ запросе, или QueryDict может быть пустым и при этом запрос в целом имеет смысл. Или наоборот, ты думаешь, что запрос пустой, а там какой-нибудь токен из скрытых инпутов, да и мало-ли что вообще. Вот еще конкретный пример:
    def post(self, request, *args, **kwargs):
        if request.POST:
            print "POST"
        else:
            print "Not POST???"
            print request.method
            data = json.loads(request.body)
            print data

>>> Not POST???
>>> POST
>>> {"columns": {"name": 50, "code": 30, "id": 20}}



Офлайн

#5 Июль 7, 2015 07:33:23

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

FishHook
Не очень понимаю, как запрос попал в представление, если он не был отправлен.
Извини. не дописал. Я говорил о именно POST запросе . т.е. в теле запроса содержался POST заголовок.

FishHook
я тебя понял и ты конечно же прав. Вся соль лишь в том что чаще код пишется под достаточно конкретные задачи. Зная что должно быть на входе, что должно быть на выходе, а все остальное тчо не подходит - отсеивается как варианты. Ну думаю дальше чисто дисскуссия и индивидуальный стиль программирования. Но это уже оффтопик.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#6 Июль 7, 2015 07:58:13

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

JOHN_16
Зная что должно быть на входе, что должно быть на выходе, а все остальное тчо не подходит - отсеивается как варианты.

Мы же не пэхэпэшники, мы же знаем, что фронтенд и бэкенд смешивать нельзя. Веб приложение нужно писать так, чтобы в любой момент можно было бы переписать клиентскую часть с нуля не ломая серверную часть. Если завтра тебе понадобится angular, то весь твой код, где есть if request.POST придется переписывать.



Офлайн

#7 Июль 7, 2015 12:05:22

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

FishHook
Я не совсем понял что ты имеешь ввиду ( где именно это происходит) говоря о смешениие фронт и бек эндов и request.POST. С ангуляром не знаком. МОжешь пояснить на примере?



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#8 Июль 7, 2015 16:28:35

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

Да пример, собственно, выше был, вот он

    def post(self, request, *args, **kwargs):
        if request.POST:
            print "POST"
        else:
            print "Not POST???"
            print request.method
            data = json.loads(request.body)
            print data
Если ты получаешь данные так, как того ожидает джанга, то проблем нет. Но, если данные от клиента отдаёт сторонний фреймворк типа ангуляра, то могут быть нюансы. В данном случае bool(request.POST) вернет False, так как формально словарь пустой. На самом деле в запросе есть данные в body. Если вся обработка запроса локализуется в текущей функции, то проблем нет. Но в более-менее крупном проекте, рутина организована в базовых классах/функциях и middleware, и здесь проверка if request.POST в итоге обернется проблемой, избежать которую весьма просто: всегда явно проверять тип запроса, как того рекомендуют создатели джанги.

По идее, базовым классам, миддлварям, функциям и прочим библиотекам должно быть всё-равно с какого фронтенда идут данные.



Отредактировано FishHook (Июль 7, 2015 16:30:25)

Офлайн

#9 Июль 7, 2015 23:47:52

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

FishHook
а какой смысл посылать ПОСТ запрос без самого ПОСТ заголовка? Он не для этого предназначен. Для этого ГЕТ есть. Выходит какая то не правильная ситуация. Мол у менять есть феррари и я им вместо трактора огород вспахиваю, ну и что что она предназначена для скорострных трасс - вперед мол едет, значит и с этим должна справиться. Это конечно шуточная аналогия :).
Я к тому что может изначально правильные технологии и методы использовать? Я про то что требует стандарт HTML - запрашивать страницы методом GET, передавать данные форм POST ну и т.д. POST же имеет и другие преимущества в сравнении с GET.

P.S. FishHook я все понял о чем ты говоришь; и да разработчики в документации говорят о проверке вида request.method
P.S.S. а с какой целью Ангуляр посылает пост запрос, без самого заголовка и с данными в теле обычного html ?



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#10 Июль 8, 2015 06:03:12

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Работа с пользовательскими данными | Комментарии для статьи

JOHN_16
P.S.S. а с какой целью Ангуляр посылает пост запрос, без самого заголовка и с данными в теле обычного html ?
Всё не так, ангуляр отправляет нормальный валидный запрос, просто джанга живёт в прошлом веке и не может его нормально интерпретировать. Джанга ждёт body в таком формате
csrfmiddlewaretoken=v7ZLpCRt8PcHpRwQvgT13ggVdxjGGn9c&time=08.07.2015+02%3A55%3A18&action=start_stoppage&code=
она получает запрос, парсит его и помещает все параметры в свой QueryDict

ангуляр присылает то же самое, с теми же заголовками, но в json (что вообще то логично для ajax)
{csrfmiddlewaretoken:"v7ZLpCRt8PcHpRwQvgT13ggVdxjGGn9", time: "08.07.2015 09:00:00", action: "start_stoppage", "code":null}
Джанга не может распарсить этот body и в итоге QueryDict у тебя пустой. При том, что это POST - валидный и не пустой.



Офлайн

  • Начало
  • » Django
  • » Работа с пользовательскими данными | Комментарии для статьи[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version