编写视图 — Django 文档
编写视图
视图函数,或简称 view,是一个 Python 函数,它接受一个 Web 请求并返回一个 Web 响应。 此响应可以是网页的 HTML 内容、重定向、404 错误、XML 文档或图像。 . . 或任何东西,真的。 视图本身包含返回该响应所需的任意逻辑。 这段代码可以放在你想要的任何地方,只要它在你的 Python 路径上。 没有其他要求——可以这么说,没有“魔法”。 为了将代码 放在 的某处,约定是将视图放在名为 views.py
的文件中,放置在您的项目或应用程序目录中。
一个简单的视图
这是一个以 HTML 文档形式返回当前日期和时间的视图:
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
让我们一次一行地浏览这段代码:
首先,我们从 django.http 模块中导入类 HttpResponse,以及 Python 的
datetime
库。接下来,我们定义一个名为
current_datetime
的函数。 这是视图函数。 每个视图函数都将一个 HttpRequest 对象作为它的第一个参数,通常命名为request
。请注意,视图函数的名称无关紧要; 它不必以某种方式命名,以便 Django 识别它。 我们在这里称它为
current_datetime
,因为这个名字清楚地表明了它的作用。该视图返回一个 HttpResponse 对象,其中包含生成的响应。 每个视图函数负责返回一个 HttpResponse 对象。 (也有例外,但我们稍后会谈到。)
将 URL 映射到视图
因此,回顾一下,这个视图函数返回一个包含当前日期和时间的 HTML 页面。 要在特定 URL 上显示此视图,您需要创建一个 URLconf; 有关说明,请参阅 URL 调度程序 。
返回错误
Django 提供了返回 HTTP 错误代码的帮助。 除了 200(这意味着 “OK”)之外,还有许多常见 HTTP 状态代码的 HttpResponse 子类。 您可以在 request/response 文档中找到可用子类的完整列表。 返回这些子类之一的实例而不是正常的 HttpResponse 以表示错误。 例如:
from django.http import HttpResponse, HttpResponseNotFound
def my_view(request):
# ...
if foo:
return HttpResponseNotFound('<h1>Page not found</h1>')
else:
return HttpResponse('<h1>Page was found</h1>')
每个可能的 HTTP 响应代码都没有专门的子类,因为它们中的许多不会那么常见。 但是,如 HttpResponse 文档中所述,您还可以将 HTTP 状态代码传递到 HttpResponse 的构造函数中,以便为您喜欢的任何状态代码创建返回类。 例如:
from django.http import HttpResponse
def my_view(request):
# ...
# Return a "created" (201) response code.
return HttpResponse(status=201)
因为 404 错误是迄今为止最常见的 HTTP 错误,所以有一种更简单的方法来处理这些错误。
Http404 异常
- class django.http.Http404
当您返回诸如 HttpResponseNotFound 之类的错误时,您负责定义生成的错误页面的 HTML:
return HttpResponseNotFound('<h1>Page not found</h1>')
为方便起见,并且因为在您的站点上拥有一致的 404 错误页面是个好主意,Django 提供了 Http404
异常。 如果在视图函数中的任何一点引发 Http404
,Django 将捕获它并返回应用程序的标准错误页面以及 HTTP 错误代码 404。
用法示例:
from django.http import Http404
from django.shortcuts import render
from polls.models import Poll
def detail(request, poll_id):
try:
p = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise Http404("Poll does not exist")
return render(request, 'polls/detail.html', {'poll': p})
为了在 Django 返回 404 时显示自定义的 HTML,您可以创建一个名为 404.html
的 HTML 模板并将其放置在模板树的顶层。 当 :setting:`DEBUG` 设置为 False
时,将提供此模板。
当 :setting:`DEBUG` 为 True
时,您可以向 Http404
提供消息,它将出现在标准 404 调试模板中。 将这些消息用于调试目的; 它们通常不适合在生产 404 模板中使用。
自定义错误视图
Django 中的默认错误视图应该足以满足大多数 Web 应用程序的需求,但如果您需要任何自定义行为,则可以轻松覆盖。 在您的 URLconf 中指定如下所示的处理程序(将它们设置在其他任何地方将不起作用)。
page_not_found() 视图被 handler404 覆盖:
handler404 = 'mysite.views.my_custom_page_not_found_view'
server_error() 视图被 handler500 覆盖:
handler500 = 'mysite.views.my_custom_error_view'
permission_denied() 视图被 handler403 覆盖:
handler403 = 'mysite.views.my_custom_permission_denied_view'
bad_request() 视图被 handler400 覆盖:
handler400 = 'mysite.views.my_custom_bad_request_view'
测试自定义错误视图
要测试自定义错误处理程序的响应,请在测试视图中引发适当的异常。 例如:
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.test import SimpleTestCase, override_settings
from django.urls import path
def response_error_handler(request, exception=None):
return HttpResponse('Error handler content', status=403)
def permission_denied_view(request):
raise PermissionDenied
urlpatterns = [
path('403/', permission_denied_view),
]
handler403 = response_error_handler
# ROOT_URLCONF must specify the module that contains handler403 = ...
@override_settings(ROOT_URLCONF=__name__)
class CustomErrorHandlerTests(SimpleTestCase):
def test_handler_renders_template_response(self):
response = self.client.get('/403/')
# Make assertions on the response here. For example:
self.assertContains(response, 'Error handler content', status_code=403)
异步视图
3.1 版中的新功能。
除了是同步函数,视图也可以是异步(“async”)函数,通常使用 Python 的 async def
语法定义。 Django 将自动检测这些并在异步上下文中运行它们。 但是,您需要使用基于 ASGI 的异步服务器来获得它们的性能优势。
这是异步视图的示例:
import datetime
from django.http import HttpResponse
async def current_datetime(request):
now = datetime.datetime.now()
html = '<html><body>It is now %s.</body></html>' % now
return HttpResponse(html)
您可以在 异步支持 中阅读更多关于 Django 的异步支持以及如何最好地使用异步视图的信息。