一、自定义错误视图
在做一个web时,总是会出现各种错误,如400、403、404、500等。一般开发都要做对应的处理,给一些友好提示,或返回一些公益广告等。
在Django中,默认提供了常见的错误处理方式,比如:
1 2 3 4 |
handler404 = 'polls.views.my_custom_page_not_found_view' handler500 = 'polls.views.my_custom_error_view' handler403 = 'polls.views.my_custom_permission_denied_view' handler400 = 'polls.views.my_custom_bad_request_view' |
handler*名称都是固定的,不能随意更改,Django已经约定好的,不同的状态码对应不同的错误。另外这些配置都需要写入到项目入口的urls.py文件中,不能写入到应用的urls.py文件中,不然不会生效。对于值需要引入写好的视图函数,写绝对路径。
为什么写入应用urls.py文件不生效呢?因为当程序抛出Http404异常时,Django会加载一个特殊的view方法处理404错误。默认地, 它是django.views.defaults.page_not_found,负责加载和渲染404.html模板文件。这意味着我们必须在模板根目录定义404.html模板文件,该模板文件应用于所有的404异常。
比如下面写一个404函数:
1 2 3 4 5 6 7 8 9 10 11 |
# ./project_name/urls.py .... handler404 = 'polls.views.polls_404_handlers' # ./polls/views from django.shortcuts import render, get_object_or_404 from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound from django.urls import reverse def polls_404_handlers(request): return HttpResponseNotFound('Page Not Found') |
这里使用HttpResponseNotFound方法返回,你用HttpResponse也同样可以返回,但是HttpResponseNotFound返回的状态码是404,才符合需求;而用HttpResponse返回的状态码是200,如果到了web服务器nginx也会获取到200状态码。
测试时需要把Django debug关了,默认是开启的,不然看不到结果;取而代之的是,traceback信息。
1 2 |
# ./project_name/settings.py DEBUG = False |
再生产环境中一定要关掉,不然程序有问题时,用户就可以看到你的程序结构。
然后服务器重启,在没有问题的情况下,随便访问一个不存在的页面,就会返回我们定义返回的内容:
1 2 |
$ curl http://127.0.0.1:8000/NotPage Page Not Found |
可以看到访问日志如下(状态404):
1 |
[26/Oct/2017 10:47:25] "GET /NotPage HTTP/1.1" 404 14 |
二、HttpResponse子类
Django包含很多HttpResponse子类,用来处理不同的HTTP响应类型,和HttpResponse一样,这些子类在django.http中。
HttpResponseRedirect
构造函数接受单个参数,重定向到的URL。可以是全URL (e.g., ‘http://search.yahoo.com/’)或者相对URL(e.g., ‘/search/’),注意:这将返回HTTP状态码302。
HttpResponsePermanentRedirect
同HttpResponseRedirect一样,但是返回永久重定向(HTTP状态码301)。
HttpResponseNotModified
构造函数不需要参数。使用此项可指定自用户上次请求以来页面未被修改。
HttpResponseBadRequest
返回400 status code。
HttpResponseNotFound
返回404 status code。
HttpResponseForbidden
返回403 status code。
HttpResponseNotAllowed
返回405 status code,它需要一个必须的参数:一个允许的方法的list (e.g., [‘GET’,’POST’])。
HttpResponseGone
返回410 status code。
HttpResponseServerError
返回500 status code。
当然,你也可以自己定义不包含在上表中的HttpResponse子类。