Django преобразование представления функции в представление класса

У меня проблема с преобразованием представления на основе функций в представление на основе классов, функции

VIEWS.PY

@ login_required
def favourite_add(request, id):
    post = get_object_or_404(Perfumes, id=id)
    if post.favourites.filter(id=request.user.id).exists():
        post.favourites.remove(request.user)
    else:
        post.favourites.add(request.user)
    return HttpResponseRedirect(request.META['HTTP_REFERER'])
URLS.PY

urlpatterns = [
    path('fav/<int:id>/', views.favourite_add, name='favourite_add'),                 
]
TEMPLATE.HTML

        <div>
            <a href="{% url 'favourite_add' perfume.id %}" class="btn btn-outline-primary">Add</a>
        </div>

В общем, цель - получить id определенного парфюма на странице, и, используя функцию get_object_or_404, я извлекаю его объект из базы данных Perfumes - переменную post. Далее я хочу получить id вошедшего в систему пользователя и проверить, есть ли id вышеуказанного пользователя в разделе избранного в переменной post. Если нет, то добавить, в противном случае удалить id пользователя в раздел избранного переменной post.

Основанная на функциях, вероятно, отлично подходит для того, что вам нужно.

В любом случае, вот представление, которое должно выполнять ту же работу, что и ваше:

urls.py:

urlpatterns = [
    path('fav/<int:id>/', views.FavouriteView.as_view(), name='favourite_add'),                 
]

views.py:

from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin

class FavouriteView(LoginRequiredMixin, View):

    def get(self, *args, **kwargs):
        post = get_object_or_404(Perfumes, id=self.kwargs.get('id'))
        if post.favourites.filter(id=self.request.user.id).exists():
            post.favourites.remove(self.request.user)
        else:
            post.favourites.add(self.request.user)
        return HttpResponseRedirect(self.request.META['HTTP_REFERER'])

Рекомендую посмотреть что-нибудь вроде https://ccbv.co.uk/, чтобы помочь вам понять представления на основе классов

Вы не должны делать это через GET запрос, так как в разделе safe methods спецификации HTTP [w3.org] говорится:

В частности, было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение для выполнения какого-либо действия, кроме извлечения. Эти методы должны считаться "безопасными".

Таким образом,

GET и HEAD должны иметь безпобочных эффектов. Например, вы можете работать с POST-запросом:

from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin

class FavouriteView(LoginRequiredMixin, View):

    def post(self, request, id):
        perfume = get_object_or_404(Perfumes, id=id)
        if request.user in perfume.favourites.all():
            perfume.favourites.remove(request.user)
        else:
            perfume.favourites.add(request.user)
        return HttpResponseRedirect(request.META['HTTP_REFERER'])

Затем вы создаете мини-форму для выполнения POST-запроса:

<form method="post" action="{% url 'favourite_add' perfume.id %}">
    {% csrf_token %}
    <button class="btn btn-outline-primary">Add</button>
</form>

Примечание: обычно модели Django присваивается сингулярное имя, поэтому Perfume вместо Perfumes.

Вернуться на верх