如何在 django 3.1 中执行允许 DELETE 方法的基于 class 的删除视图?

How to do a class based delete view that allows DELETE method in django 3.1?

在 Django 3.1 中,典型的 DeleteView 接受 GET 和 POST。

https://docs.djangoproject.com/en/3.1/ref/class-based-views/generic-editing/#deleteview

我转载如下:

A view that displays a confirmation page and deletes an existing object. The given object will only be deleted if the request method is POST. If this view is fetched via GET, it will display a confirmation page that should contain a form that POSTs to the same URL.

如何创建一个基于 class 的视图并接受 DELETE 方法的 DELETEView?

Tldr;我选择在服务器端使用 303,以便它可以正确重定向到列表视图

长话短说

在适用于 Spring(Java 框架)的 SO 答案中,问题与我的问题相同。

  1. 发送删除
  2. 然后服务器端想使用 302
  3. 重定向
  4. 302 将使用先例方法,列表通常不接受 DELETE 作为先例方法。仅 POST、GET 和 HEAD 作为先例方法

这似乎是网络框架问题。但事实并非如此。它似乎是最明智的网络框架采用的惯例。

有 3 个有缺点的解决方案:

1。推翻惯例

允许后端 Web 框架接受 DELETE 作为 302 的先例方法。

缺点:按照惯例不太好

2。让客户端处理重定向

发回 200 然后客户端将重定向回列表视图

缺点:这会导致两个请求,而 htmx-delete 不能那样工作。它将发送一个 DELETE 方法请求,然后获取返回的任何内容并立即交换。我喜欢这个,所以我想保留这个。一个请求而不是两个来解决这个问题。

3。使用 303 进行重定向

删除成功后,做一个303重定向到列表视图(我选择这个)

缺点:303 不适用于 HTTP/1.0 和旧版浏览器。但这在 2021 年不是问题,并且在未来将继续成为问题。

最后我写了自己的deleteview

from django.views.generic.detail import BaseDetailView

class DeleteThingView(BaseDetailView):
    http_method_names = ["delete"]
    model = Thing

    def delete(self, request, *args, **kwargs):
        self.object = self.get_object()
        self.object.delete()
        response = redirect(reverse_lazy("things-list"))
        response.status_code = 303
        return response