django 将函数视图转换为 class 视图

django convert function view to class view

我在从 function-based 视图转换为 class-based 视图时遇到问题,函数

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 函数,我从香水数据库中提取它的 object - post变量。接下来,我想检索 logged-in 用户的 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/ 的内容,以帮助您理解基于 class 的观点

您不应通过 GET 请求执行此操作,如 safe methods section of the HTTP specifications [w3.org] 所述:

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe".

GET 和 HEAD 因此应该 没有 副作用。例如,您可以使用 POST 请求:

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

class FavouriteView(LoginRequiredMixin, View):

    def <strong>post</strong>(self, request, <strong>id</strong>):
        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'])

然后您发出 mini-form 以发出 POST 请求:

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

Note: normally a Django model is given a singular name, so Perfume instead of Perfumes.