{"title":"Writing views","version":"4.0","locale":"ko","docname":"topics/http/views","url":"/ko/4.0/topics/http/views/","canonical":"https://djangodocs.dev/ko/4.0/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. This response can be the HTML contents of a web page,…","html":"<h1>Writing views<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 “magic,” 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\"><span class=\"pre\">views.py</span></code>, placed in your project or\napplication directory.</p>\n<section id=\"a-simple-view\">\n<h2>A simple view<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=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">current_datetime</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">now</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span>\n    <span class=\"n\">html</span> <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> <span class=\"n\">now</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">html</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>한 줄씩 이 코드를 밟아나가 봅시다.</p>\n<ul>\n<li><p>첫 번째로,  <a class=\"reference internal\" href=\"/ko/4.0/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\"><span class=\"pre\">django.http</span></code></a> 모듈로부터 <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> 클래스를, 파이썬의 <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime</span></code> 라이브러리와 함께 임포트합니다.</p></li>\n<li><p>다음으로 <code class=\"docutils literal notranslate\"><span class=\"pre\">current_datetime</span></code> 라는 함수를 정의합니다. 이것이 뷰 함수입니다. 각각의 뷰 함수는 <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a>  객체를 첫 인자로 가지며, 이 객체는 일반적으로 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>request``라는 이름입니다.</p>\n<p>뷰 함수의 이름은 중요하지 않습니다. Django가 인식하도록 만들기 위해 특정한 방법으로 이름지을 필요는 없습니다. 여기서는 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>current_datetime``이라 부를 것이고, 이 이름이 하는 일을 분명하게 표현하기 때문입니다.</p>\n</li>\n<li><p>뷰는 생성된 응답을 담고 있는 <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> 객체를 반환합니다. 각 뷰 함수는  <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> 객체를 반환하는 역할을 합니다. (예외가 있지만, 나중에 알아보겠습니다)</p></li>\n</ul>\n<aside class=\"admonition-django-s-time-zone admonition\">\n<p class=\"admonition-title\">Django’s Time Zone</p>\n<p>Django는 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>America/Chicago``가 기본으로 설정되어 있는 <a class=\"reference internal\" href=\"/ko/4.0/ref/settings/#std-setting-TIME_ZONE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TIME_ZONE</span></code></a> 설정을 가지고 있습니다. 이 위치는 아마 여러분이 사시는 곳이 아니므로, 설정 파일에서 바꿀 수 있습니다.</p>\n</aside>\n</section>\n<section id=\"mapping-urls-to-views\">\n<h2>Mapping URLs to views<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에 이 뷰를 표시하고 싶다면, <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">*</span></a>URLconf*를 만들어야 합니다. 자세한 내용은 <a class=\"reference internal\" href=\"/ko/4.0/topics/http/urls/\"><span class=\"doc\">URL dispatcher</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 provides help for returning HTTP error codes. There are subclasses of\n<a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> for a number of common HTTP status codes\nother than 200 (which means <em>“OK”</em>). You can find the full list of available\nsubclasses in the <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#ref-httpresponse-subclasses\"><span class=\"std std-ref\">request/response</span></a>\ndocumentation. Return an instance of one of those subclasses instead of a\nnormal <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> in order to signify an error. For\nexample:</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=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span><span class=\"p\">,</span> <span class=\"n\">HttpResponseNotFound</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">if</span> <span class=\"n\">foo</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">HttpResponseNotFound</span><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> <span class=\"n\">HttpResponse</span><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>There isn’t a specialized subclass for every possible HTTP response code,\nsince many of them aren’t going to be that common. However, as documented in\nthe <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> documentation, you can also pass the\nHTTP status code into the constructor for <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>\nto create a return class for any status code you like. For example:</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=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><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> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">status</span><span class=\"o\">=</span><span class=\"mi\">201</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Because 404 errors are by far the most common HTTP error, there’s an easier way\nto handle those errors.</p>\n<section id=\"the-http404-exception\">\n<h3>The <code class=\"docutils literal notranslate\"><span class=\"pre\">Http404</span></code> exception<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\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">django.http.</span></span><span class=\"sig-name descname\"><span class=\"pre\">Http404</span></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>When you return an error such as <a class=\"reference internal\" href=\"/ko/4.0/ref/request-response/#django.http.HttpResponseNotFound\" title=\"django.http.HttpResponseNotFound\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponseNotFound</span></code></a>,\nyou’re responsible for defining the HTML of the resulting error page:</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> <span class=\"n\">HttpResponseNotFound</span><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>For convenience, and because it’s a good idea to have a consistent 404 error page\nacross your site, Django provides an <code class=\"docutils literal notranslate\"><span class=\"pre\">Http404</span></code> exception. If you raise\n<code class=\"docutils literal notranslate\"><span class=\"pre\">Http404</span></code> at any point in a view function, Django will catch it and return the\nstandard error page for your application, along with an HTTP error code 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=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Http404</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">polls.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Poll</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">poll_id</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Poll</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">poll_id</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"n\">Poll</span><span class=\"o\">.</span><span class=\"n\">DoesNotExist</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">Http404</span><span class=\"p\">(</span><span class=\"s2\">&quot;Poll does not exist&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><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> <span class=\"n\">p</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>In order to show customized HTML when Django returns a 404, you can create an\nHTML template named <code class=\"docutils literal notranslate\"><span class=\"pre\">404.html</span></code> and place it in the top level of your\ntemplate tree. This template will then be served when <a class=\"reference internal\" href=\"/ko/4.0/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> is set\nto <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>.</p>\n<p>When <a class=\"reference internal\" href=\"/ko/4.0/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> is <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, you can provide a message to <code class=\"docutils literal notranslate\"><span class=\"pre\">Http404</span></code> and\nit will appear in the standard 404 debug template. Use these messages for\ndebugging purposes; they generally aren’t suitable for use in a production 404\ntemplate.</p>\n</section>\n</section>\n<section id=\"customizing-error-views\">\n<span id=\"id1\"></span><h2>Customizing error views<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>The <a class=\"reference internal\" href=\"/ko/4.0/ref/views/#django.views.defaults.page_not_found\" title=\"django.views.defaults.page_not_found\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">page_not_found()</span></code></a> view is overridden by\n<a class=\"reference internal\" href=\"/ko/4.0/ref/urls/#django.conf.urls.handler404\" title=\"django.conf.urls.handler404\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">handler404</span></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=\"n\">handler404</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_page_not_found_view&#39;</span>\n</code></pre></div>\n<p>The <a class=\"reference internal\" href=\"/ko/4.0/ref/views/#django.views.defaults.server_error\" title=\"django.views.defaults.server_error\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">server_error()</span></code></a> view is overridden by\n<a class=\"reference internal\" href=\"/ko/4.0/ref/urls/#django.conf.urls.handler500\" title=\"django.conf.urls.handler500\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">handler500</span></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=\"n\">handler500</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_error_view&#39;</span>\n</code></pre></div>\n<p>The <a class=\"reference internal\" href=\"/ko/4.0/ref/views/#django.views.defaults.permission_denied\" title=\"django.views.defaults.permission_denied\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">permission_denied()</span></code></a> view is overridden by\n<a class=\"reference internal\" href=\"/ko/4.0/ref/urls/#django.conf.urls.handler403\" title=\"django.conf.urls.handler403\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">handler403</span></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=\"n\">handler403</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;mysite.views.my_custom_permission_denied_view&#39;</span>\n</code></pre></div>\n<p>The <a class=\"reference internal\" href=\"/ko/4.0/ref/views/#django.views.defaults.bad_request\" title=\"django.views.defaults.bad_request\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">bad_request()</span></code></a> view is overridden by\n<a class=\"reference internal\" href=\"/ko/4.0/ref/urls/#django.conf.urls.handler400\" title=\"django.conf.urls.handler400\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">handler400</span></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=\"n\">handler400</span> <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\">\n<p class=\"admonition-title\">더 보기</p>\n<p>Use the <a class=\"reference internal\" href=\"/ko/4.0/ref/settings/#std-setting-CSRF_FAILURE_VIEW\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_FAILURE_VIEW</span></code></a> setting to override the CSRF error\nview.</p>\n</aside>\n<section id=\"testing-custom-error-views\">\n<h3>Testing custom error views<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>To test the response of a custom error handler, raise the appropriate exception\nin a test view. For example:</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=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">PermissionDenied</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SimpleTestCase</span><span class=\"p\">,</span> <span class=\"n\">override_settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">response_error_handler</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">exception</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s1\">&#39;Error handler content&#39;</span><span class=\"p\">,</span> <span class=\"n\">status</span><span class=\"o\">=</span><span class=\"mi\">403</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">permission_denied_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">raise</span> <span class=\"n\">PermissionDenied</span>\n\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;403/&#39;</span><span class=\"p\">,</span> <span class=\"n\">permission_denied_view</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n\n<span class=\"n\">handler403</span> <span class=\"o\">=</span> <span class=\"n\">response_error_handler</span>\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><span class=\"n\">ROOT_URLCONF</span><span class=\"o\">=</span><span class=\"vm\">__name__</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomErrorHandlerTests</span><span class=\"p\">(</span><span class=\"n\">SimpleTestCase</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_handler_renders_template_response</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><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><span class=\"n\">assertContains</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Error handler content&#39;</span><span class=\"p\">,</span> <span class=\"n\">status_code</span><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>As well as being synchronous functions, views can also be asynchronous\n(“async”) functions, normally defined using Python’s <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> syntax.\nDjango will automatically detect these and run them in an async context.\nHowever, you will need to use an async server based on ASGI to get their\nperformance benefits.</p>\n<p>Here’s an example of an async view:</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=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">current_datetime</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">now</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span>\n    <span class=\"n\">html</span> <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> <span class=\"n\">now</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">html</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>You can read more about Django’s async support, and how to best use async\nviews, in <a class=\"reference internal\" href=\"/ko/4.0/topics/async/\"><span class=\"doc\">비동기 지원</span></a>.</p>\n</section>","rootId":"writing-views","toc":[{"title":"A simple view","anchor":"a-simple-view","children":[]},{"title":"Mapping URLs to views","anchor":"mapping-urls-to-views","children":[]},{"title":"에러 반환","anchor":"returning-errors","children":[{"title":"The Http404 exception","anchor":"the-http404-exception","children":[]}]},{"title":"Customizing error views","anchor":"customizing-error-views","children":[{"title":"Testing custom error views","anchor":"testing-custom-error-views","children":[]}]},{"title":"비동기 뷰","anchor":"async-views","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Django 사용하기","url":"/ko/4.0/topics/"},{"docname":"topics/http/index","title":"Handling HTTP requests","url":"/ko/4.0/topics/http/"}],"prev":{"docname":"topics/http/urls","title":"URL dispatcher","url":"/ko/4.0/topics/http/urls/"},"next":{"docname":"topics/http/decorators","title":"View decorators","url":"/ko/4.0/topics/http/decorators/"},"formats":{"html":"/ko/4.0/topics/http/views/","markdown":"/ko/4.0/topics/http/views.md","json":"/ko/4.0/topics/http/views.json"},"source":"https://github.com/django/django/blob/stable/4.0.x/docs/topics/http/views.txt","official":"https://docs.djangoproject.com/ko/4.0/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","1.11"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}