Как в Django CBV переопределить результат POST запроса?

Я пытаюсь добавить систему лайков к постам блога используя такую форму:
<form action="/article/like/{{ article.id }}/" method="post">
    {% csrf_token %}
    <input hidden name="like" value="+">
    <input type="submit" value="-">
</form>


Как используя CBV поймать результат POST запроса и переопределить и дополнить его?
То есть создать условие: если в форме передается like=+ то...
Единственный способ который я нашел это переопределить form_valid примерно так:
def form_valid(self, form):
        instance = form.save(commit=False)
        instance.user = request.user
        instance.save() 
        return redirect(self.get_success_url())


Только я не совсем понимаю где содержится мое значение like.
  • Вопрос задан
  • 593 просмотра
Решения вопроса 1
@deliro
Агрессивное программирование
Ответ на твой вопрос выглядит так:
def post(self, request, *args, **kwargs):
    ...

Но. Зачем тебе переопределять POST в CreateView? Дополни form_valid до такого вида:
def form_valid(self, form):
    instance = form.save(commit=False)
    if instance.like == '+':
        instance.user = request.user
        instance.save()
    else:
        bad_mojo()
    return redirect(self.get_success_url())


При этом непонятно, зачем в модели поле like, которое должно равняться "+". Может, у тебя его нет и ты просто запутался?
Тривиальная система лайков за статью будет выглядеть так:

в models.py:
class Like(Model):  # Модель лайков
    user = ForeignKey(User)


class Article(Model):  # Твоя модель статьи
    # Чтобы уменьшить количество записей в таблице Like, просто будем присваивать статьям
    # один и тот же лайк через М2М связь.
    likes = ManyToManyField(Like)

    def like(self, user):
        try:
            like = Like.objects.get(user=user)
            self.likes.add(like)
        except Like.DoesNotExist:
            self.likes.create(user=user)


Вьюху делаем максимально тупой (так как модель у нас жирная):
class LikeArticle(SingleObjectMixin, View):
    model = Article

    def post(self, request, *args, **kwargs):
        obj = self.get_object()
        obj.like(request.user)
        return redirect(obj)  # Чтобы использовать такую форму, нужно определить метод get_absolute_url для Article


В урлы мы пишем имя вьюхи, а не (говно)хардкодим в шаблонах:
...
url(r'article/(?P<pk>\d+)/like$', LikeArticle.as_view(), name='like-article'),
# Заметь, article/<id>/like, а не article/like/<id>. Архитектурно так более верно.
...


Ну и в шаблон осталось вставить:
<form action="{% url 'like-article' object.pk %}" method="POST">{% csrf_token %}
    {# Где object - экземпляр статьи #}
    <input type="submit"/>
</form>
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
pinkevich
@pinkevich
Python Developer
во вьюхе значение like можно получить через instance.cleaned_data.get('like')

А когда станешь понимать, что происходит, то raw значение можно будет взять из
self.request.POST.get('like')
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы