{"title":"编写视图","version":"4.1","locale":"zh-hans","docname":"topics/http/views","url":"/zh-hans/4.1/topics/http/views/","canonical":"https://djangodocs.dev/zh-hans/4.1/topics/http/views/","summary":"A view function, or view for short, is a Python function that takes a web request and returns a web response.","html":"<h1>编写视图<a class=\"heading-anchor\" href=\"#writing-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>A view function, or <em>view</em> for short, is a Python function that takes a\nweb request and returns a web response. This response can be the HTML contents\nof a web page, or a redirect, or a 404 error, or an XML document, or an image .\n. . or anything, really. The view itself contains whatever arbitrary logic is\nnecessary to return that response. This code can live anywhere you want, as long\nas it's on your Python path. There's no other requirement--no &quot;magic,&quot; so to\nspeak. For the sake of putting the code <em>somewhere</em>, the convention is to\nput views in a file called <code class=\"docutils literal notranslate\">views.py</code>, placed in your project or\napplication directory.</p>\n<section id=\"a-simple-view\">\n<h2>一个简单的视图<a class=\"heading-anchor\" href=\"#a-simple-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>这里是一个以 HTML 文档形式返回当前日期和时间的视图：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n<span class=\"kn\">import</span> <span class=\"nn\">datetime</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">current_datetime</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    now <span class=\"o\">=</span> datetime<span class=\"o\">.</span>datetime<span class=\"o\">.</span>now<span class=\"p\">()</span>\n    html <span class=\"o\">=</span> <span class=\"s2\">&quot;&lt;html&gt;&lt;body&gt;It is now </span><span class=\"si\">%s</span><span class=\"s2\">.&lt;/body&gt;&lt;/html&gt;&quot;</span> <span class=\"o\">%</span> now\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span>html<span class=\"p\">)</span>\n</code></pre></div>\n<p>让我们来完成这个代码：</p>\n<ul>\n<li><p>首先，我们从 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#module-django.http\" title=\"django.http: Classes dealing with HTTP requests and responses.\"><code class=\"xref py py-mod docutils literal notranslate\">django.http</code></a> 模块导入类 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> ，以及 Python 的 <code class=\"docutils literal notranslate\">datetime</code> 库。</p></li>\n<li><p>然后，我们定义一个名为 <code class=\"docutils literal notranslate\">current_datetime</code> 的函数。这是一个视图函数。每个视图函数都将 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\">HttpRequest</code></a> 对象作为第一个参数，通常名为 <code class=\"docutils literal notranslate\">request</code> 。</p>\n<p>注意视图函数名称无关紧要；它不需要以特定的名称来让 Django 识别它。我们在这里命名 <code class=\"docutils literal notranslate\">current_datetime</code> ，因为这个名字可以清楚的表示它的用途。</p>\n</li>\n<li><p>视图返回一个包含生成的响应的 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> 对象。每个视图函数都要返回 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> 对象。（有例外，我们稍后再讲）</p></li>\n</ul>\n<aside class=\"admonition-django-s-time-zone admonition\" role=\"note\">\n<p class=\"admonition-title\">Django 时区</p>\n<p>Django 包含 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/settings/#std-setting-TIME_ZONE\"><code class=\"xref std std-setting docutils literal notranslate\">TIME_ZONE</code></a> 设置，默认是 <code class=\"docutils literal notranslate\">America/Chicago</code> 。你可以在配置文件里改成你所在的时区。</p>\n</aside>\n</section>\n<section id=\"mapping-urls-to-views\">\n<h2>将 URL 映射到视图<a class=\"heading-anchor\" href=\"#mapping-urls-to-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>因此，回顾一下，这个视图函数返回包含当前日期时间的HTML页面。如果在特定的 URL 使用这个视图，你需要创建 <em>URLconf</em> ；查看 <a class=\"reference internal\" href=\"/zh-hans/4.1/topics/http/urls/\"><span class=\"doc\">URL调度器</span></a> 的操作说明。</p>\n</section>\n<section id=\"returning-errors\">\n<h2>返回错误信息<a class=\"heading-anchor\" href=\"#returning-errors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django 提供了有关返回 HTTP 错误代码的帮助。<a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> 的子类除了200外，还有很多常见的 HTTP 状态代码。你可以在 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#ref-httpresponse-subclasses\"><span class=\"std std-ref\">request/response</span></a> 文档中找到所有可用子类的列表。返回这些子类中某个子类的实例而不是 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> 来表示错误。比如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse<span class=\"p\">,</span> HttpResponseNotFound\n\n<span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">if</span> foo<span class=\"p\">:</span>\n        <span class=\"k\">return</span> HttpResponseNotFound<span class=\"p\">(</span><span class=\"s1\">&#39;&lt;h1&gt;Page not found&lt;/h1&gt;&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span><span class=\"s1\">&#39;&lt;h1&gt;Page was found&lt;/h1&gt;&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>并不是每个可用 HTTP 响应代码都有专门指定的子类，因为它们很多并不常见。然而，如 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> 文档中所述的那样，你也可以将 HTTP 状态代码传递给 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> 的构造函数，这样就可以为任何状态代码创建返回类。比如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n\n<span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n\n    <span class=\"c1\"># Return a &quot;created&quot; (201) response code.</span>\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span>status<span class=\"o\">=</span><span class=\"mi\">201</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>因为 404 错误是最常见的 HTTP 错误，这里有更简单的方法来处理这些错误。</p>\n<section id=\"the-http404-exception\">\n<h3><code class=\"docutils literal notranslate\">Http404</code> 异常<a class=\"heading-anchor\" href=\"#the-http404-exception\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.http.Http404\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-prename descclassname\">django.http.</span><span class=\"sig-name descname\">Http404</span><a class=\"heading-anchor\" href=\"#django.http.Http404\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>当你返回错误，例如 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/request-response/#django.http.HttpResponseNotFound\" title=\"django.http.HttpResponseNotFound\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponseNotFound</code></a> ，你需要定义错误页面的 HTML 。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">return</span> HttpResponseNotFound<span class=\"p\">(</span><span class=\"s1\">&#39;&lt;h1&gt;Page not found&lt;/h1&gt;&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>为方便起见，在你的网站里有个一致的 404 错误页面是个好办法，Django 提供 <code class=\"docutils literal notranslate\">Http404</code> 异常。如果你在视图的任何地方引发了 <code class=\"docutils literal notranslate\">Http404</code> ，Django 会捕捉到它并且返回标准的错误页面，连同 HTTP 错误代码 404 。</p>\n<p>用法示例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> Http404\n<span class=\"kn\">from</span> <span class=\"nn\">django.shortcuts</span> <span class=\"kn\">import</span> render\n<span class=\"kn\">from</span> <span class=\"nn\">polls.models</span> <span class=\"kn\">import</span> Poll\n\n<span class=\"k\">def</span> <span class=\"nf\">detail</span><span class=\"p\">(</span>request<span class=\"p\">,</span> poll_id<span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        p <span class=\"o\">=</span> Poll<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span>poll_id<span class=\"p\">)</span>\n    <span class=\"k\">except</span> Poll<span class=\"o\">.</span>DoesNotExist<span class=\"p\">:</span>\n        <span class=\"k\">raise</span> Http404<span class=\"p\">(</span><span class=\"s2\">&quot;Poll does not exist&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> render<span class=\"p\">(</span>request<span class=\"p\">,</span> <span class=\"s1\">&#39;polls/detail.html&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;poll&#39;</span><span class=\"p\">:</span> p<span class=\"p\">})</span>\n</code></pre></div>\n<p>为了在 Django 返回404时显示自定义的 HTML，你可以创建名为  <code class=\"docutils literal notranslate\">404.html</code> 的HTML模板，并将其放置在你的模板树顶层。这个模板将在 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\">DEBUG</code></a> 设为 <code class=\"docutils literal notranslate\">False</code> 时提供。</p>\n<p>当 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\">DEBUG</code></a> 为 <code class=\"docutils literal notranslate\">True</code> 时，你可以提供 <code class=\"docutils literal notranslate\">Http404</code> 信息，并且在标准的 404 调试模板里显示。使用这些信息来调试；它们通常不适合在生产环境下的404模板。</p>\n</section>\n</section>\n<section id=\"customizing-error-views\">\n<span id=\"id1\"></span><h2>自定义报错视图<a class=\"heading-anchor\" href=\"#customizing-error-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>The default error views in Django should suffice for most web applications,\nbut can easily be overridden if you need any custom behavior. Specify the\nhandlers as seen below in your URLconf (setting them anywhere else will have no\neffect).</p>\n<p>可以用 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/urls/#django.conf.urls.handler404\" title=\"django.conf.urls.handler404\"><code class=\"xref py py-data docutils literal notranslate\">handler404</code></a>: 覆盖 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/views/#django.views.defaults.page_not_found\" title=\"django.views.defaults.page_not_found\"><code class=\"xref py py-func docutils literal notranslate\">page_not_found()</code></a> 视图：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>handler404 <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_page_not_found_view&#39;</span>\n</code></pre></div>\n<p>可以用 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/urls/#django.conf.urls.handler500\" title=\"django.conf.urls.handler500\"><code class=\"xref py py-data docutils literal notranslate\">handler500</code></a>: 覆盖 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/views/#django.views.defaults.server_error\" title=\"django.views.defaults.server_error\"><code class=\"xref py py-func docutils literal notranslate\">server_error()</code></a> 视图：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>handler500 <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_error_view&#39;</span>\n</code></pre></div>\n<p>可以用 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/urls/#django.conf.urls.handler403\" title=\"django.conf.urls.handler403\"><code class=\"xref py py-data docutils literal notranslate\">handler403</code></a>: 覆盖 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/views/#django.views.defaults.permission_denied\" title=\"django.views.defaults.permission_denied\"><code class=\"xref py py-func docutils literal notranslate\">permission_denied()</code></a> 视图：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>handler403 <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_permission_denied_view&#39;</span>\n</code></pre></div>\n<p>可以用 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/urls/#django.conf.urls.handler400\" title=\"django.conf.urls.handler400\"><code class=\"xref py py-data docutils literal notranslate\">handler400</code></a>: 覆盖 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/views/#django.views.defaults.bad_request\" title=\"django.views.defaults.bad_request\"><code class=\"xref py py-func docutils literal notranslate\">bad_request()</code></a> 视图：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>handler400 <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_bad_request_view&#39;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<p>使用 <a class=\"reference internal\" href=\"/zh-hans/4.1/ref/settings/#std-setting-CSRF_FAILURE_VIEW\"><code class=\"xref std std-setting docutils literal notranslate\">CSRF_FAILURE_VIEW</code></a> 来覆盖 CSRF 报错视图。</p>\n</aside>\n<section id=\"testing-custom-error-views\">\n<h3>测试自定义报错视图<a class=\"heading-anchor\" href=\"#testing-custom-error-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>为了测试自定义报错处理的响应，可以适当地在测试视图里引发异常。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.core.exceptions</span> <span class=\"kn\">import</span> PermissionDenied\n<span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n<span class=\"kn\">from</span> <span class=\"nn\">django.test</span> <span class=\"kn\">import</span> SimpleTestCase<span class=\"p\">,</span> override_settings\n<span class=\"kn\">from</span> <span class=\"nn\">django.urls</span> <span class=\"kn\">import</span> path\n\n\n<span class=\"k\">def</span> <span class=\"nf\">response_error_handler</span><span class=\"p\">(</span>request<span class=\"p\">,</span> exception<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span><span class=\"s1\">&#39;Error handler content&#39;</span><span class=\"p\">,</span> status<span class=\"o\">=</span><span class=\"mi\">403</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">permission_denied_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"k\">raise</span> PermissionDenied\n\n\nurlpatterns <span class=\"o\">=</span> <span class=\"p\">[</span>\n    path<span class=\"p\">(</span><span class=\"s1\">&#39;403/&#39;</span><span class=\"p\">,</span> permission_denied_view<span class=\"p\">),</span>\n<span class=\"p\">]</span>\n\nhandler403 <span class=\"o\">=</span> response_error_handler\n\n\n<span class=\"c1\"># ROOT_URLCONF must specify the module that contains handler403 = ...</span>\n<span class=\"nd\">@override_settings</span><span class=\"p\">(</span>ROOT_URLCONF<span class=\"o\">=</span><span class=\"vm\">__name__</span><span class=\"p\">)</span>\n<span class=\"k\">class</span> <span class=\"nc\">CustomErrorHandlerTests</span><span class=\"p\">(</span>SimpleTestCase<span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">test_handler_renders_template_response</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        response <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>client<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"s1\">&#39;/403/&#39;</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Make assertions on the response here. For example:</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span>assertContains<span class=\"p\">(</span>response<span class=\"p\">,</span> <span class=\"s1\">&#39;Error handler content&#39;</span><span class=\"p\">,</span> status_code<span class=\"o\">=</span><span class=\"mi\">403</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"async-views\">\n<span id=\"id2\"></span><h2>异步视图<a class=\"heading-anchor\" href=\"#async-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>除了同步函数，视图也可以是异步（“async”）函数，通常使用 Python 的 <code class=\"docutils literal notranslate\">async def</code> 语法定义。Django 会自动检测这些函数，并在异步上下文中运行它们。但是，你需要使用基于 ASGI 的异步服务器来获得它们的性能优势。</p>\n<p>下面是一个异步视图的例子：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span> <span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n\n<span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">current_datetime</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    now <span class=\"o\">=</span> datetime<span class=\"o\">.</span>datetime<span class=\"o\">.</span>now<span class=\"p\">()</span>\n    html <span class=\"o\">=</span> <span class=\"s1\">&#39;&lt;html&gt;&lt;body&gt;It is now </span><span class=\"si\">%s</span><span class=\"s1\">.&lt;/body&gt;&lt;/html&gt;&#39;</span> <span class=\"o\">%</span> now\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span>html<span class=\"p\">)</span>\n</code></pre></div>\n<p>你可以在 <a class=\"reference internal\" href=\"/zh-hans/4.1/topics/async/\"><span class=\"doc\">异步支持</span></a> 中阅读更多关于 Django 的异步支持，以及如何最好的使用异步视图。</p>\n</section>","rootId":"writing-views","toc":[{"title":"一个简单的视图","anchor":"a-simple-view","children":[]},{"title":"将 URL 映射到视图","anchor":"mapping-urls-to-views","children":[]},{"title":"返回错误信息","anchor":"returning-errors","children":[{"title":"Http404 异常","anchor":"the-http404-exception","children":[]}]},{"title":"自定义报错视图","anchor":"customizing-error-views","children":[{"title":"测试自定义报错视图","anchor":"testing-custom-error-views","children":[]}]},{"title":"异步视图","anchor":"async-views","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/4.1/topics/"},{"docname":"topics/http/index","title":"处理 HTTP 请求","url":"/zh-hans/4.1/topics/http/"}],"prev":{"docname":"topics/http/urls","title":"URL调度器","url":"/zh-hans/4.1/topics/http/urls/"},"next":{"docname":"topics/http/decorators","title":"视图装饰器","url":"/zh-hans/4.1/topics/http/decorators/"},"formats":{"html":"/zh-hans/4.1/topics/http/views/","markdown":"/zh-hans/4.1/topics/http/views.md","json":"/zh-hans/4.1/topics/http/views.json"},"source":"https://github.com/django/django/blob/stable/4.1.x/docs/topics/http/views.txt","official":"https://docs.djangoproject.com/zh-hans/4.1/topics/http/views/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}