Django: URL 到特定的请求方法

Django: URL to specific request method

我正在使用 Django,我正在使用基于 class 的视图和 urls。因此,在 mu classes 中,我有以下方法:postgetputdelete.

示例:

class MyClassView(View):
    def get(self, request, id=None):
        return HttpResponse('GET request')

    def post(self, request):
        return HttpResponse('POST request')

    def put(self, request, id):
        return HttpResponse('PUT request')

    def delete(self, request, id):
        return HttpResponse('DELETE request')

所以在我的 URL 中我有类似的东西:

from django.urls import path
from . import views

urlpatterns =[
    path('my-class/', views.MyClassView.as_view()),
    path('my-class/<int:id>/', views.MyClassView.as_view()),
    path('my-class/create/', views.MyClassView.as_view()),
    path('my-class/update/<int:id>/', views.MyClassView.as_view()),
    path('my-class/delete/<int:id>/', views.MyClassView.as_view()),
]

这很好用!当我向 /my-class 发送 GET 请求时,我得到 "GET request",当我向 /my-class/create 发送 POST 请求时,我得到 "POST request" 其他人也一样 URLs.

问题是,当我向 /my-class/ 发送 POST 请求时,我得到 "POST request",当我向 /my-class/creare 发送 GET 请求时,我得到得到 "GET request"

我需要 URL 仅适用于特定的请求方法。也就是说,url /my-class/create 应该只适用于 POST 方法,url /my-class/update 应该只适用于 PUT 方法等等。

我该怎么做?我在文档中甚至在这里进行了很多研究,但没有找到解决方案。

您可以使用 http_method_names 限制 http 方法。但是你应该分开视图 类.

举个例子:

from .views import PostView

urlpatterns = [
    path('only_post/', PostView.as_view(), name='post'),
]

你的观点:

class PostView(View):
    http_method_names = ['post']

    def post(self, request):
        return HttpResponse('POST request')

现在你只能向这个url发送一个post请求,否则你会得到一个HTTP ERROR 405错误。

我试图开发一个稍微轻便的解决方案,这样您就不必为每个请求方法创建一个 class。

受 .NET Core 中此功能操作的启发,我创建了一个 decotator 以在 class 的每个方法中使用。这个装饰器的代码如下所示:

from django.http import HttpResponse

def http_method_list(methods):
    def http_methods_decorator(func):
        def function_wrapper(self, request, **kwargs):
            methods = [method.upper() for method in methods]
            if not request.method.upper() in methods:
                return HttpResponse(status=405) # not allowed

            return func(self, request, **kwargs)
        return function_wrapper
    return http_methods_decorator

所以在class中我们使用:

class MyView(View):

    @http_method_list(["GET"])
    def get(self, request):
        return HttpResponse("Only GET requests")

    @http_method_list(["POST"])
    def post(self, request):
        return HttpResponse("Only POST requests")

    # and so on

现在 get() 方法,例如,只能由 GET 请求执行,post() 和 class 视图中的其他方法也是如此。

我希望这对其他人有用。

您可以将 http_method_names 直接传递给 .as_view() 方法。 在 Django==3.2.3

上测试
urlpatterns =[
    path('my-class/', views.MyClassView.as_view(http_method_names=['get'])),
    path('my-class/<int:id>/', views.MyClassView.as_view(http_method_names=['get'])),
    path('my-class/create/', views.MyClassView.as_view(http_method_names=['post'])),
    path('my-class/update/<int:id>/', views.MyClassView.as_view(http_method_names=['put'])),
    path('my-class/delete/<int:id>/', views.MyClassView.as_view(http_method_names=['delete'])),
]

对于未来的 Google 员工, 请为此检查 django 文档 decorators in views