{"title":"はじめての Django アプリ作成、その 3","version":"3.0","locale":"ja","docname":"intro/tutorial03","url":"/ja/3.0/intro/tutorial03/","canonical":"https://djangodocs.dev/ja/3.0/intro/tutorial03/","summary":"このチュートリアルは チュートリアルその 2 の続きです。ここでは、引続き Web 投票アプリケーションの開発を例にして、公開用のインタフェース、ビュー(view) の作成を焦点に解説します。 困ったときは: このチュートリアルの実行に問題がある場合は、FAQ の Getting Help セクションに進んでください。…","html":"<h1>はじめての Django アプリ作成、その 3<a class=\"heading-anchor\" href=\"#writing-your-first-django-app-part-3\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>このチュートリアルは <a class=\"reference internal\" href=\"/ja/3.0/intro/tutorial02/\"><span class=\"doc\">チュートリアルその 2</span></a> の続きです。ここでは、引続き Web 投票アプリケーションの開発を例にして、公開用のインタフェース、ビュー(view) の作成を焦点に解説します。</p>\n<aside class=\"admonition-where-to-get-help admonition\">\n<p class=\"admonition-title\">困ったときは:</p>\n<p>このチュートリアルの実行に問題がある場合は、FAQ の <a class=\"reference internal\" href=\"/ja/3.0/faq/help/\"><span class=\"doc\">Getting Help</span></a> セクションに進んでください。</p>\n</aside>\n<section id=\"overview\">\n<h2>オーバービュー<a class=\"heading-anchor\" href=\"#overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>ビューとは、 Django のアプリケーションにおいて特定の機能を提供するウェブペー ジの「型 (type)」であり、各々のテンプレートを持っています。例えばブログアプリケーションなら、以下のようなビューがあるでしょう:</p>\n<ul class=\"simple\">\n<li><p>Blog ホームページ - 最新エントリーをいくつか表示</p></li>\n<li><p>エントリー詳細ページ - 1エントリーへのパーマリンク (permalink) ページ</p></li>\n<li><p>年ごとのアーカイブページ - 指定された年のエントリーの月を全て表示</p></li>\n<li><p>月ごとのアーカイブページ - 指定された月のエントリーの日をすべて表示</p></li>\n<li><p>日ごとのアーカイブページ - 指定された日の全てのエントリーを表示</p></li>\n<li><p>コメント投稿 - エントリーに対するコメントの投稿を受付</p></li>\n</ul>\n<p>投票アプリケーションでは、以下4つのビューを作成します:</p>\n<ul class=\"simple\">\n<li><p>質問 &quot;インデックス&quot; ページ -- 最新の質問をいくつか表示</p></li>\n<li><p>質問 &quot;詳細&quot; ページ -- 結果を表示せず、質問テキストと投票フォームを表示</p></li>\n<li><p>質問 &quot;結果&quot; ページ -- 特定の質問の結果を表示</p></li>\n<li><p>投票ページ -- 特定の質問の選択を投票として受付</p></li>\n</ul>\n<p>Django では、ウェブページとコンテンツはビューによって提供されます。各ビューは単純に Python 関数 (クラスベースビューの場合はメソッド) として実装されています。 Django はビューを、リクエストされた URL (正確には、URLのドメイン以降の部分) から決定します。</p>\n<p>Now in your time on the web you may have come across such beauties as\n<code class=\"docutils literal notranslate\"><span class=\"pre\">ME2/Sites/dirmod.htm?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B</span></code>.\nYou will be pleased to know that Django allows us much more elegant\n<em>URL patterns</em> than that.</p>\n<p>URLパターンは、URLを単に一般化したものです。たとえば、 <code class=\"docutils literal notranslate\"><span class=\"pre\">/newsarchive/&lt;year&gt;/&lt;month&gt;/</span></code> などです。</p>\n<p>URLからビューを得るために、Django は「URLconf」と呼ばれているものを使います。URLconf はURLパターンをビューにマッピングします。</p>\n<p>このチュートリアルでは URLconf の基本的な使い方を知ってもらいます。より詳しくは <a class=\"reference internal\" href=\"/ja/3.0/topics/http/urls/\"><span class=\"doc\">URL ディスパッチャ</span></a> を参照してください。</p>\n</section>\n<section id=\"writing-more-views\">\n<h2>もっとビューを書いてみる<a class=\"heading-anchor\" href=\"#writing-more-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>それではもう少しviewを <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code> に追加していきましょう。これから追加するviewでは引数をとります。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/views.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><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\">question_id</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;You&#39;re looking at question </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span> <span class=\"o\">%</span> <span class=\"n\">question_id</span><span class=\"p\">)</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">results</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;You&#39;re looking at the results of question </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">response</span> <span class=\"o\">%</span> <span class=\"n\">question_id</span><span class=\"p\">)</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">vote</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;You&#39;re voting on question </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span> <span class=\"o\">%</span> <span class=\"n\">question_id</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>次の <a class=\"reference internal\" href=\"/ja/3.0/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">path()</span></code></a> コールを追加して、新しいviewを <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> モジュールと結びつけます。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/urls.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><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<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">views</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ex: /polls/</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/results/</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/results/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">results</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;results&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/vote/</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/vote/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">vote</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;vote&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>お使いのブラウザで、 &quot;/polls/34/&quot; を見てください。 <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> メソッドが実行され、URLで提供したIDが表示されます。 &quot;/polls/34/results/&quot; と &quot;/polls/34/vote/&quot; も試してください。結果と投票ページのプレースホルダがそれぞれ表示されます。</p>\n<p>誰かがWebサイトの 「/polls/34/」 をリクエストすると、 Django は <a class=\"reference internal\" href=\"/ja/3.0/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ROOT_URLCONF</span></code></a> に指定されている Python モジュール <code class=\"docutils literal notranslate\"><span class=\"pre\">mysite.urls</span></code> をロードします。そのモジュール内の <code class=\"docutils literal notranslate\"><span class=\"pre\">urlpatterns</span></code> という変数を探し、順番にパターンを検査していきます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/</span></code> にマッチした箇所を見つけた後、一致した文字列 (<code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;polls/&quot;</span></code>) を取り除き、残りの文字列である &quot;34/&quot; を次の処理のために 『polls.urls』 の URLconf に渡します。これは <code class=\"docutils literal notranslate\"><span class=\"pre\">'&lt;int：question_id&gt;/'</span></code> に一致し、結果として下記のように <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> が呼び出されます。</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\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">=&lt;</span><span class=\"n\">HttpRequest</span> <span class=\"nb\">object</span><span class=\"o\">&gt;</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"o\">=</span><span class=\"mi\">34</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">question_id=34</span></code> の部分は <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;int:question_id&gt;</span></code> から来ています。 山括弧を使用すると、URLの一部が「キャプチャ」され、キーワード引数としてビュー関数に送信します。 文字列の <code class=\"docutils literal notranslate\"><span class=\"pre\">:question_id&gt;</span></code> 部分は、一致するパターンを識別するために使用される名前を定義し、<code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;int:</span></code> 部分は、URLパスのこの部分に一致するパターンを決定するコンバータです。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">.html</span></code> のような文字列をURLに追加する必要はありません。ただし、次のようにすれば、表現できます:</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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;polls/latest.html&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">),</span>\n</code></pre></div>\n<p>とはいえ、こんな阿呆なことはやめましょう。</p>\n</section>\n<section id=\"write-views-that-actually-do-something\">\n<h2>実際に動作するビューを書く<a class=\"heading-anchor\" href=\"#write-views-that-actually-do-something\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>各ビューには二つの役割があります: 一つはリクエストされたページのコンテンツを含む <a class=\"reference internal\" href=\"/ja/3.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=\"/ja/3.0/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> のような例外の送出です。それ以外の処理はユーザ次第です。</p>\n<p>ビューはデータベースからレコードを読みだしても、読み出さなくてもかまいません。 Django のテンプレートシステム、あるいはサードパーティの Python テンプ レートシステムを使ってもよいですし、使わなくてもかまいません。 PDF ファイルを生成しても、 XML を出力しても、 ZIP ファイルをその場で生成してもかまいません。 Python ライブラリを使ってやりたいことを何でも実現できます。</p>\n<p>Django にとって必要なのは <a class=\"reference internal\" href=\"/ja/3.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>\n<p>簡単のため、 <a class=\"reference internal\" href=\"/ja/3.0/intro/tutorial02/\"><span class=\"doc\">チュートリアルその 2</span></a> で解説した Django のデータベース API を使ってみましょう。試しに次のような <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code> ビューを作ります。これは、システム上にある最新の 5 件の質問項目をカンマで区切り、日付順に表示するビューです:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/views.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python 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=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">latest_question_list</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-pub_date&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;, &#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"n\">q</span><span class=\"o\">.</span><span class=\"n\">question_text</span> <span class=\"k\">for</span> <span class=\"n\">q</span> <span class=\"ow\">in</span> <span class=\"n\">latest_question_list</span><span class=\"p\">])</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">output</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Leave the rest of the views (detail, results, vote) unchanged</span>\n</code></pre></figure>\n<p>このコードには問題があります。ビューの中で、ページのデザインがハードコードされています。ページの見栄えを変更するたびに、 Python コードを編集する必要があります。 Django のテンプレートシステムを使って、ビューから使用できるテンプレートを作成し、Python からデザインを分離しましょう。</p>\n<p>最初に、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> ディレクトリの中に、 <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code>  ディレクトリを作成します。 Django はそこからテンプレートを探します。</p>\n<p>プロジェクトの <a class=\"reference internal\" href=\"/ja/3.0/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TEMPLATES</span></code></a> には、Django がどのようにテンプレートをロードしレンダリングするかが書かれています。デフォルトの設定ファイルでは、 <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> バックエンドが設定されており、その <a class=\"reference internal\" href=\"/ja/3.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">APP_DIRS</span></code></a> のオプションが <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> になっています。規約により、 <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> は <a class=\"reference internal\" href=\"/ja/3.0/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a> のそれぞれの &quot;templates&quot; サブディレクトリを検索します。</p>\n<p>先ほど作成した <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> ディレクトリ内で <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> というディレクトリを作成し、さらにその中に <code class=\"docutils literal notranslate\"><span class=\"pre\">index.html</span></code> というファイルを作成してください。つまり、テンプレートは <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code> に書く必要があります。 <code class=\"docutils literal notranslate\"><span class=\"pre\">app_directories</span></code> テンプレートローダは前述のように動くため、Django 内でこのテンプレートを単に <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> のように参照できます。</p>\n<aside class=\"admonition-template-namespacing admonition\">\n<p class=\"admonition-title\">テンプレートの名前空間</p>\n<p>作ったテンプレートを (<code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> という別のサブディレクトリを作らずに) 直接 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates</span></code> の中に置いてもいいのではないか、と思うかもしれませんね。しかし、それは実際には悪い考えです。Django は、名前がマッチした最初のテンプレートを使用するので、もし <em>異なる</em> アプリケーションの中に同じ名前のテンプレートがあった場合、Django はそれらを区別することができません。そのため、Django に正しいテンプレートを教えてあげる必要がありますが、一番簡単な方法は、それらに <em>名前空間を与える</em>  ことです。アプリケーションと同じ名前をつけた <em>もう一つの</em> ディレクトリの中にテンプレートを置いたのは、そういうわけなのです。</p>\n</aside>\n<p>テンプレートには次のコードを書きます:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\">polls/templates/polls/index.html</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">latest_question_list</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">question</span> <span class=\"k\">in</span> <span class=\"nv\">latest_question_list</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;/polls/</span><span class=\"cp\">{{</span> <span class=\"nv\">question.id</span> <span class=\"cp\">}}</span><span class=\"s\">/&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">else</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>No polls are available.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></figure>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>チュートリアルを短くするために、すべてのテンプレートの例では不完全なHTMLを使用しています。独自のプロジェクトでは <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>完全な HTML ドキュメント`__を使用する必要があります。</p>\n</aside>\n<p>このテンプレートを使用するために <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code> の <code class=\"docutils literal notranslate\"><span class=\"pre\">index</span></code> ビューを更新してみましょう:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/views.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python 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\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">loader</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">latest_question_list</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-pub_date&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    <span class=\"n\">template</span> <span class=\"o\">=</span> <span class=\"n\">loader</span><span class=\"o\">.</span><span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;polls/index.html&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;latest_question_list&#39;</span><span class=\"p\">:</span> <span class=\"n\">latest_question_list</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">))</span>\n</code></pre></figure>\n<p>このコードは、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> というテンプレートをロードし、そこにコンテキストを渡します。コンテキストは、テンプレート変数名を Python オブジェクトにマッピングする辞書です。</p>\n<p>ブラウザで &quot;/polls/&quot; を開くと、箇条書きのリストが表示されるはずです（リストには、  <a class=\"reference internal\" href=\"/ja/3.0/intro/tutorial02/\"><span class=\"doc\">チュートリアルその2</span></a> で作った &quot;What's up&quot; という質問が入っていますね）。リンクは質問の詳細ページを指します。</p>\n<section id=\"a-shortcut-render\">\n<h3>ショートカット: <a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render()</span></code></a><a class=\"heading-anchor\" href=\"#a-shortcut-render\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>テンプレートをロードしてコンテキストに値を入れ、テンプレートをレンダリングした結果を <a class=\"reference internal\" href=\"/ja/3.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>  オブジェクトで返す、というイディオムは非常によく使われます。 Django はこのためのショートカットを提供します。これを使って <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code> ビューを書き換えてみましょう:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/views.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><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\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">latest_question_list</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-pub_date&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;latest_question_list&#39;</span><span class=\"p\">:</span> <span class=\"n\">latest_question_list</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/index.html&#39;</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>全部の view をこのように書き換えてしまえば、 <a class=\"reference internal\" href=\"/ja/3.0/topics/templates/#module-django.template.loader\" title=\"django.template.loader\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">loader</span></code></a> や <a class=\"reference internal\" href=\"/ja/3.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> を import する必要はなくなります (<code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code> 、 <code class=\"docutils literal notranslate\"><span class=\"pre\">results</span></code> 、 <code class=\"docutils literal notranslate\"><span class=\"pre\">vote</span></code> を引き続きスタブメソッドにするなら、 <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code> はそのままにしておいたほうがいいでしょう)。</p>\n<p><a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render()</span></code></a> 関数は、第1引数として request オブジェクトを、第2引数としてテンプレート名を、第3引数（任意）として辞書を受け取ります。この関数はテンプレートを指定のコンテキストでレンダリングし、その <a class=\"reference internal\" href=\"/ja/3.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>\n</section>\n</section>\n<section id=\"raising-a-404-error\">\n<h2>404 エラーの送出<a class=\"heading-anchor\" href=\"#raising-a-404-error\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>さて、質問詳細ビューに取り組みましょう。このページは、指定された投票の質問文を表示するものです。ビューは次のようになります:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/views.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python 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\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n<span class=\"c1\"># ...</span>\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\">question_id</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">question</span> <span class=\"o\">=</span> <span class=\"n\">Question</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\">question_id</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"n\">Question</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;Question 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;question&#39;</span><span class=\"p\">:</span> <span class=\"n\">question</span><span class=\"p\">})</span>\n</code></pre></figure>\n<p>新しい概念が出てきました。このビューは、リクエストした ID を持つ質問が存在しないときに <a class=\"reference internal\" href=\"/ja/3.0/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> を送出します。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code> テンプレートに何を書けばよいかは後で解説しますが、さしあたって上の例題を動かしたければ、単に:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\">polls/templates/polls/detail.html</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">question</span> <span class=\"cp\">}}</span>\n</code></pre></figure>\n<p>と書いておいてください。</p>\n<section id=\"a-shortcut-get-object-or-404\">\n<h3>ショートカット: <a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a><a class=\"heading-anchor\" href=\"#a-shortcut-get-object-or-404\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/3.0/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a> を実行し、オブジェクトが存在しない場合には <a class=\"reference internal\" href=\"/ja/3.0/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> を送出することは非常によく使われるイディオムです。 Django はこのためのショートカットを提供しています。ショートカットを使って、 <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> ビューを書き換えてみましょう:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/views.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><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\">get_object_or_404</span><span class=\"p\">,</span> <span class=\"n\">render</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n<span class=\"c1\"># ...</span>\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\">question_id</span><span class=\"p\">):</span>\n    <span class=\"n\">question</span> <span class=\"o\">=</span> <span class=\"n\">get_object_or_404</span><span class=\"p\">(</span><span class=\"n\">Question</span><span class=\"p\">,</span> <span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">question_id</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;question&#39;</span><span class=\"p\">:</span> <span class=\"n\">question</span><span class=\"p\">})</span>\n</code></pre></figure>\n<p>The <a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a> function takes a Django model\nas its first argument and an arbitrary number of keyword arguments, which it\npasses to the <a class=\"reference internal\" href=\"/ja/3.0/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a> function of the\nmodel's manager. It raises <a class=\"reference internal\" href=\"/ja/3.0/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> if the object doesn't\nexist.</p>\n<aside class=\"admonition-philosophy admonition\">\n<p class=\"admonition-title\">設計思想</p>\n<p>なぜ <a class=\"reference internal\" href=\"/ja/3.0/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ObjectDoesNotExist</span></code></a> 例外を高水準で自動的にキャッチせず、ヘルパー関数 <a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a> を使うのでしょうか、また、なぜモデル API に <a class=\"reference internal\" href=\"/ja/3.0/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ObjectDoesNotExist</span></code></a> ではなく、 <a class=\"reference internal\" href=\"/ja/3.0/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> を送出させるのでしょうか?</p>\n<p>答えは、モデルレイヤとビューレイヤをカップリングしてしまうからです。 Django の最も大きな目標の一つは、ルーズカップリングの維持にあります。いくつかの制御カップリングは、 <a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#module-django.shortcuts\" title=\"django.shortcuts: Convenience shortcuts that span multiple levels of Django's MVC stack.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.shortcuts</span></code></a> モジュールの中にあります。</p>\n</aside>\n<p><a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.get_list_or_404\" title=\"django.shortcuts.get_list_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_list_or_404()</span></code></a> という関数もあります。この関数は  <a class=\"reference internal\" href=\"/ja/3.0/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a> と同じように動きますが、 <a class=\"reference internal\" href=\"/ja/3.0/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a> ではなく、  <a class=\"reference internal\" href=\"/ja/3.0/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">filter()</span></code></a> を使います。リストが空の場合は <a class=\"reference internal\" href=\"/ja/3.0/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> を送出します。</p>\n</section>\n</section>\n<section id=\"use-the-template-system\">\n<h2>テンプレートシステムを使う<a class=\"heading-anchor\" href=\"#use-the-template-system\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>投票アプリの <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> ビューに戻りましょう。コンテキスト変数を  <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code> とすると、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code> テンプレートは次のようになります:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\">polls/templates/polls/detail.html</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">choice</span> <span class=\"k\">in</span> <span class=\"nv\">question.choice_set.all</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">choice.choice_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></figure>\n<p>テンプレートシステムは、変数の属性にアクセスするためにドット検索の構文を使用します。 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">question.question_text</span> <span class=\"pre\">}}</span></code> を例にすると、はじめに Django は <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code> オブジェクトに辞書検索を行います。それに失敗したら、今度は属性として検索を行い、このケースの場合は成功します。もし属性の検索に失敗すると、リストインデックスでの検索を行います。</p>\n<p>メソッドの呼び出しは <a class=\"reference internal\" href=\"/ja/3.0/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for</span> <span class=\"pre\">%}</span></code></a> ループの中で行われています。 <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all</span></code> は、 Python コードの <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all()</span></code> と解釈されます。その結果、<code class=\"docutils literal notranslate\"><span class=\"pre\">Choice</span></code> オブジェクトからなるイテレーション可能オブジェクトを返し、 <a class=\"reference internal\" href=\"/ja/3.0/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for</span> <span class=\"pre\">%}</span></code></a> タグで使えるようになります。</p>\n<p>テンプレートの詳しい動作は  <a class=\"reference internal\" href=\"/ja/3.0/topics/templates/\"><span class=\"doc\">テンプレートガイド</span></a> を参照してください。</p>\n</section>\n<section id=\"removing-hardcoded-urls-in-templates\">\n<h2>テンプレート内のハードコードされたURLを削除<a class=\"heading-anchor\" href=\"#removing-hardcoded-urls-in-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> テンプレートで質問へのリンクを書いたとき、リンクの一部は次のようにハードコードされていました:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;/polls/</span><span class=\"cp\">{{</span> <span class=\"nv\">question.id</span> <span class=\"cp\">}}</span><span class=\"s\">/&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>このハードコードされた、密結合のアプローチの問題は、プロジェクトにテンプレートが多数ある場合、URLの変更が困難になってしまうことです。しかし、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> モジュール の <a class=\"reference internal\" href=\"/ja/3.0/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">path()</span></code></a> 関数で name 引数を定義したので、テンプレートタグの <code class=\"docutils literal notranslate\"><span class=\"pre\">{％url％}</span></code> を使用して、URL 設定で定義されている特定の URL パスへの依存をなくすことができます:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">url</span> <span class=\"s1\">&#39;detail&#39;</span> <span class=\"nv\">question.id</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>これが機能するのは、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> モジュールに指定されたURLの定義を検索するからです。 'detail' のURL名は以下の箇所で定義されています:</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=\"o\">...</span>\n<span class=\"c1\"># the &#39;name&#39; value as called by the {% url %} template tag</span>\n<span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>投票の詳細ビューの URL を何か他のものに変更したい場合、たとえば  <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/specifics/12/</span></code> のように変更したいとき、対象となるテンプレートを変更する代わりに、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code> を変更します:</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=\"o\">...</span>\n<span class=\"c1\"># added the word &#39;specifics&#39;</span>\n<span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;specifics/&lt;int:question_id&gt;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n</section>\n<section id=\"namespacing-url-names\">\n<h2>URL 名の名前空間<a class=\"heading-anchor\" href=\"#namespacing-url-names\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>このチュートリアルプロジェクトが持つアプリは <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> アプリ1つだけです。実際の Django プロジェクトでは、5個、10個、20個、あるいはそれ以上のアプリがあるかもしれません。 Django はどうやってこれらの間の URL 名を区別するのでしょうか？ 例えば、 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> アプリは <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code> ビューを含みますが、同じプロジェクトにブログのためのアプリがあり、そのアプリも同名のビューを含むかもしれません。 <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">url</span> <span class=\"pre\">%}</span></code> テンプレートタグを使ったとき、 Django はどのアプリのビューに対して url を作成すればいいでしょうか？ これを Django にどう知らせればいいでしょうか。</p>\n<p>答えは、 URLconf に名前空間を追加すること、です。どうぞ <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code> ファイル内で <code class=\"docutils literal notranslate\"><span class=\"pre\">app_name</span></code> を追加し、アプリケーションの名前空間を設定してください。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">polls/urls.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><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<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">views</span>\n\n<span class=\"n\">app_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;polls&#39;</span>\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;&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/results/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">results</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;results&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/vote/&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">vote</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;vote&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>それでは <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> テンプレートを変更します。以下の形から、</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\">polls/templates/polls/index.html</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">url</span> <span class=\"s1\">&#39;detail&#39;</span> <span class=\"nv\">question.id</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></figure>\n<p>以下の形にし、名前空間つきの詳細ビューを指すようにします:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\">polls/templates/polls/index.html</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">url</span> <span class=\"s1\">&#39;polls:detail&#39;</span> <span class=\"nv\">question.id</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></figure>\n<p>ビューを書けるようになったら、 <a class=\"reference internal\" href=\"/ja/3.0/intro/tutorial04/\"><span class=\"doc\">チュートリアルその4</span></a>  に進んで、簡単なフォームの処理と汎用ビューについて学びましょう。</p>\n</section>","rootId":"writing-your-first-django-app-part-3","toc":[{"title":"オーバービュー","anchor":"overview","children":[]},{"title":"もっとビューを書いてみる","anchor":"writing-more-views","children":[]},{"title":"実際に動作するビューを書く","anchor":"write-views-that-actually-do-something","children":[{"title":"ショートカット: render()","anchor":"a-shortcut-render","children":[]}]},{"title":"404 エラーの送出","anchor":"raising-a-404-error","children":[{"title":"ショートカット: get_object_or_404()","anchor":"a-shortcut-get-object-or-404","children":[]}]},{"title":"テンプレートシステムを使う","anchor":"use-the-template-system","children":[]},{"title":"テンプレート内のハードコードされたURLを削除","anchor":"removing-hardcoded-urls-in-templates","children":[]},{"title":"URL 名の名前空間","anchor":"namespacing-url-names","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"さぁ始めましょう","url":"/ja/3.0/intro/"}],"prev":{"docname":"intro/tutorial02","title":"はじめての Django アプリ作成、その2","url":"/ja/3.0/intro/tutorial02/"},"next":{"docname":"intro/tutorial04","title":"はじめての Django アプリ作成、その 4","url":"/ja/3.0/intro/tutorial04/"},"formats":{"html":"/ja/3.0/intro/tutorial03/","markdown":"/ja/3.0/intro/tutorial03.md","json":"/ja/3.0/intro/tutorial03.json"},"source":"https://github.com/django/django/blob/stable/3.0.x/docs/intro/tutorial03.txt","official":"https://docs.djangoproject.com/ja/3.0/intro/tutorial03/","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","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}