Django: 路由与视图 互动版

限制HTTP方法

Django框架在进行路由分发时,完全依赖于用户请求的URL,并没有考虑请求所使用 的HTTP方法。这意味着对同一个URL使用不同的HTTP方法发起请求,都将路由到同一 个视图函数被处理。

在下图的示例中,用户向URL/report/1234/使用不同的HTTP方法,发起了四次请求, 都将被Django路由到视图v_report()进行处理:

method-restrict


装饰器:require_http_method()

当然你可以在视图函数内丢弃那些期望之外的请求(比如上例中的POST /report/1234/), 但更简单的做法是使用Django预置的require_http_methods(methods)装饰器进行限制, 让框架帮你拦截那些不想要的请求。

例如,下面的示例声明了视图函数v_login()只支持GETPOST方法:

from django.views.decorators.http import require_http_methods
@require_http_methods(['GET','POST'])
def v_login(request):pass

这时,如果用户试图使用其他HTTP方法(比如DELETE)请求指向这个视图函数的URL, Django框架将自动拦截并返回405错误 —— 在HTTP协议中,405代码表示:请求的方法 不被允许。


装饰器的语法糖

有几个语法糖可以缩短require_http_method()这个装饰器的书写长度:

  • require_GET() - 声明被装饰的视图仅支持GET方法
  • require_POST() - 声明被装饰的视图仅支持POST方法
  • require_SAFE() - 声明被装饰的视图仅支持GET和HEAD方法

例如,下面的示例声明了视图函数v_index()仅支持HTTP GET方法:

@require_GET
def v_index(request):pass

限制 != 分发 :请不要错误地认为这个装饰器可以指示Django框架将使用不同 HTTP方法向同一URL发起的请求自动路由到不同的视图函数,Django做不 到这一点,你必须在视图内自行实现不同HTTP方法的分发。

修改示例中的视图v_index,使其仅支持GETPOST方法。