Django:特定请求方法的URL

Gee*_*lva 6 python django http-method

我正在使用 Django,并且使用带有 url 的基于类的视图。所以,在 mu 类中,我有以下方法:postget和。putdelete

例子:

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')
Run Code Online (Sandbox Code Playgroud)

所以在我的网址中我有类似的内容:

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()),
]
Run Code Online (Sandbox Code Playgroud)

这很好用!/my-class当我向我发送 GET 请求时,我会得到同样的"GET request"结果;当我向 a 发送 POST 请求时,/my-class/create我会得到"POST request"与其他 URL 相同的结果。

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

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

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

小智 9

您可以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'])),
]
Run Code Online (Sandbox Code Playgroud)


Gee*_*lva 5

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

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

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
Run Code Online (Sandbox Code Playgroud)

所以在课堂上我们使用:

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
Run Code Online (Sandbox Code Playgroud)

例如, Nowget()方法只能通过 GET 请求执行,对于post()View 类中的其他方法也是如此。

我希望这对其他人有用。