Django:如何使URL仅对应指定的请求方法
解决Django类视图URL限定特定HTTP方法的问题
嘿,我懂你遇到的这个问题——现在你的URL配置让同一个类视图的不同路径都开放了所有定义的HTTP方法,比如/my-class/create/居然能响应GET请求,这确实不符合你想要的“特定URL仅支持指定请求方法”的需求。别担心,Django有几种简单又优雅的方式来解决这个问题,我给你梳理一下:
方法一:在URL配置中直接指定允许的方法
这是最直接的方式,你可以在调用as_view()的时候,通过http_method_names参数明确限定该URL路径允许的HTTP方法。比如:
from django.urls import path from . import views urlpatterns = [ # /my-class/ 支持GET(带或不带id)和POST请求 path('my-class/', views.MyClassView.as_view(http_method_names=['get', 'post'])), # /my-class/<int:id>/ 支持GET、PUT、DELETE请求 path('my-class/<int:id>/', views.MyClassView.as_view(http_method_names=['get', 'put', 'delete'])), # /my-class/create/ 仅接受POST请求 path('my-class/create/', views.MyClassView.as_view(http_method_names=['post'])), # /my-class/update/<int:id>/ 仅接受PUT请求 path('my-class/update/<int:id>/', views.MyClassView.as_view(http_method_names=['put'])), # /my-class/delete/<int:id>/ 仅接受DELETE请求 path('my-class/delete/<int:id>/', views.MyClassView.as_view(http_method_names=['delete'])), ]
这样配置后,当用户向/my-class/create/发送GET请求时,Django会自动返回405 Method Not Allowed错误,完美符合你的要求。
方法二:创建视图子类限定方法
如果你的项目比较复杂,或者想让代码结构更清晰,可以创建原视图类的子类,在子类中重写http_method_names属性来限定允许的方法:
# 在你的views.py中 from django.views.generic.base import View from django.http import HttpResponse 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') # 创建子类限定方法 class MyClassCreateView(MyClassView): http_method_names = ['post'] class MyClassUpdateView(MyClassView): http_method_names = ['put'] class MyClassDeleteView(MyClassView): http_method_names = ['delete']
然后在URL配置中使用这些子类:
from django.urls import path from . import views urlpatterns = [ path('my-class/', views.MyClassView.as_view(http_method_names=['get', 'post'])), path('my-class/<int:id>/', views.MyClassView.as_view(http_method_names=['get', 'put', 'delete'])), path('my-class/create/', views.MyClassCreateView.as_view()), path('my-class/update/<int:id>/', views.MyClassUpdateView.as_view()), path('my-class/delete/<int:id>/', views.MyClassDeleteView.as_view()), ]
这种方式的好处是把方法限定的逻辑和URL配置分开,后期维护起来更方便。
额外小提示:遵循RESTful规范的话
其实如果你的API是遵循RESTful设计的,通常不需要单独的/create/、/update/路径——比如POST /my-class/就用来创建资源,PUT /my-class/<int:id>/用来更新资源,DELETE /my-class/<int:id>/用来删除资源,这样可以简化你的URL配置。不过这只是个建议,最终还是看你的项目需求来决定。
内容的提问来源于stack exchange,提问作者Edy Silva
相关产品推荐
相关产品推荐

