编写视图函数

查看函数,或 view 简而言之,是一个接受Web请求并返回Web响应的Python函数。该响应可以是网页的HTML内容、重定向、404错误、XML文档或图像。。。或者其他什么,真的。该视图本身包含返回该响应所需的任意逻辑。这段代码可以位于您想要的任何位置,只要它位于您的Python路径上。没有其他要求--可以说没有“魔法”。为了把代码放在 somewhere ,约定是将视图放在一个名为 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)

让我们一步一步地完成这段代码:

  • 首先,我们导入类 HttpResponsedjango.http 模块,以及python的 datetime 类库。

  • 接下来,我们定义一个函数 current_datetime . 这是查看功能。每个视图函数 HttpRequest 对象作为其第一个参数,通常命名为 request .

    请注意,视图函数的名称并不重要;为了让Django能够识别它,不需要以某种方式对其进行命名。我们叫它 current_datetime 这里,因为这个名字清楚地表明了它的作用。

  • 视图返回 HttpResponse 包含生成的响应的对象。每个视图函数负责返回 HttpResponse 对象。(也有例外,但我们稍后再讨论。)

Django 时区

Django包括 TIME_ZONE 设置默认为 America/Chicago . 这可能不是您居住的地方,因此您可能希望在设置文件中更改它。

将URL映射到视图

所以,概括地说,这个视图函数返回一个包含当前日期和时间的HTML页面。要在特定的URL上显示此视图,需要创建一个 URLconfURL调度器 以获取指示。

返回错误

Django提供返回HTTP错误代码的帮助。的子类 HttpResponse 对于除200以外的许多常见HTTP状态代码(这意味着 "OK" )您可以在 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 并将其放置在模板树的顶层。此模板将在以下时间提供: DEBUG 设置为 False .

什么时候? DEBUGTrue ,您可以向 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"

参见

使用 CSRF_FAILURE_VIEW 覆盖CSRF错误视图的设置。

测试自定义错误视图

要测试自定义错误处理程序的响应,请在测试视图中引发适当的异常。例如::

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)

异步视图

除了同步函数之外,视图也可以是异步(“异步”)函数,通常使用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的异步支持以及如何最好地使用异步视图的更多信息 异步支持 .