{"title":"はじめての Django アプリ作成、その 7","version":"4.1","locale":"ja","docname":"intro/tutorial07","url":"/ja/4.1/intro/tutorial07/","canonical":"https://djangodocs.dev/ja/4.1/intro/tutorial07/","summary":"This tutorial begins where Tutorial 6 left off. We're continuing the web-poll application and will focus on customizing Django's automatically-generated…","html":"<h1>はじめての Django アプリ作成、その 7<a class=\"heading-anchor\" href=\"#writing-your-first-django-app-part-7\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>This tutorial begins where <a class=\"reference internal\" href=\"/ja/4.1/intro/tutorial06/\"><span class=\"doc\">Tutorial 6</span></a> left off. We're\ncontinuing the web-poll application and will focus on customizing Django's\nautomatically-generated admin site that we first explored in <a class=\"reference internal\" href=\"/ja/4.1/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a>.</p>\n<aside class=\"admonition-where-to-get-help admonition\" role=\"note\">\n<p class=\"admonition-title\">困ったときは:</p>\n<p>このチュートリアルの実行に問題がある場合は、FAQ の <a class=\"reference internal\" href=\"/ja/4.1/faq/help/\"><span class=\"doc\">Getting Help</span></a> セクションに進んでください。</p>\n</aside>\n<section id=\"customize-the-admin-form\">\n<h2>admin フォームのカスタマイズ<a class=\"heading-anchor\" href=\"#customize-the-admin-form\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><code class=\"docutils literal notranslate\">admin.site.register(Question)</code> の呼び出しによって <code class=\"docutils literal notranslate\">Question</code> モデルを登録したことで、Django はデフォルトの形式でオブジェクトを表示できました。 admin フォームの表示方法や操作の仕方をデフォルトから変更したいこともよくあります。それには、オブジェクトを登録する時にオプションを指定します。</p>\n<p>ためしに、編集フォームでのフィールドの並び順を並べ替えてみましょう。 <code class=\"docutils literal notranslate\">admin.site.register(Question)</code> の行を以下のように置き換えてみてください。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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=\"nn\">django.contrib</span> <span class=\"kn\">import</span> admin\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"k\">class</span> <span class=\"nc\">QuestionAdmin</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>ModelAdmin<span class=\"p\">):</span>\n    fields <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;question_text&#39;</span><span class=\"p\">]</span>\n\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>register<span class=\"p\">(</span>Question<span class=\"p\">,</span> QuestionAdmin<span class=\"p\">)</span>\n</code></pre></figure>\n<p>このように、モデルの admin のオプションを変更したいときには、モデルごとに admin クラスを作成して、 <code class=\"docutils literal notranslate\">admin.site.register()</code> の 2 番目の引数に渡すと いうパターンに従ってください。</p>\n<p>上の例では、「Publication date」フィールドの表示位置を「Question」フィールドよりも前に変更しています:</p>\n<img alt=\"Fields have been reordered\" src=\"/ja/4.1/_images/admin07.png\" />\n<p>二つしかフィールドがないので、あまりぱっとした変化ではありませんね。しかし admin フォームで数十ものフィールドを操作するような場合には、直感的なフィー ルドの並び順というものはユーザビリティ上重要な要素です。</p>\n<p>また、数十ものフィールドがある場合、フォームを複数のフィールドセットに分割したいこともあるでしょう。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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=\"nn\">django.contrib</span> <span class=\"kn\">import</span> admin\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"k\">class</span> <span class=\"nc\">QuestionAdmin</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>ModelAdmin<span class=\"p\">):</span>\n    fieldsets <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span>               <span class=\"p\">{</span><span class=\"s1\">&#39;fields&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;question_text&#39;</span><span class=\"p\">]}),</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;Date information&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;fields&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">]}),</span>\n    <span class=\"p\">]</span>\n\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>register<span class=\"p\">(</span>Question<span class=\"p\">,</span> QuestionAdmin<span class=\"p\">)</span>\n</code></pre></figure>\n<p><a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets\" title=\"django.contrib.admin.ModelAdmin.fieldsets\"><code class=\"xref py py-attr docutils literal notranslate\">fieldsets</code></a> の各タプルの先頭の要素はフィールドセットのタイトルです。 フォームは以下のように表示されます。</p>\n<img alt=\"Form has fieldsets now\" src=\"/ja/4.1/_images/admin08t.png\" />\n</section>\n<section id=\"adding-related-objects\">\n<h2>リレーションを張ったオブジェクトの追加<a class=\"heading-anchor\" href=\"#adding-related-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>OK、 Question の管理ページはできました。しかし <code class=\"docutils literal notranslate\">Question</code> は複数の <code class=\"docutils literal notranslate\">Choice</code> を持つのに、管理ページには表示されていませんね。</p>\n<p>現状はそうですが、表示はできます。</p>\n<p>この問題を解決するには2つの方法があります。1つ目は、 <code class=\"docutils literal notranslate\">Question</code> と同じようにadminに <code class=\"docutils literal notranslate\">Choice</code> を登録する方法です:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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=\"nn\">django.contrib</span> <span class=\"kn\">import</span> admin\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Choice<span class=\"p\">,</span> Question\n<span class=\"c1\"># ...</span>\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>register<span class=\"p\">(</span>Choice<span class=\"p\">)</span>\n</code></pre></figure>\n<p>これで、 Django の管理サイト上で「Choice」 を選べます。「Choice の追加」フォーム は以下のようになります。</p>\n<img alt=\"Choice admin page\" src=\"/ja/4.1/_images/admin09.png\" />\n<p>このフォームでは「Question」フィールドは選択ボックスで、データベース上の全ての質問を選択できます。Django は <a class=\"reference internal\" href=\"/ja/4.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> を表示する時には <code class=\"docutils literal notranslate\">&lt;select&gt;</code> ボックスを使わねばならないということを知っているのです。今の時点では、 Question はデータベース上に一つしかないはずですね。</p>\n<p>Also note the &quot;Add another question&quot; link next to &quot;Question.&quot; Every object with\na <code class=\"docutils literal notranslate\">ForeignKey</code> relationship to another gets this for free. When you click\n&quot;Add another question&quot;, you'll get a popup window with the &quot;Add question&quot; form.\nIf you add a question in that window and click &quot;Save&quot;, Django will save the\nquestion to the database and dynamically add it as the selected choice on the\n&quot;Add choice&quot; form you're looking at.</p>\n<p>しかし、この方法は <code class=\"docutils literal notranslate\">Choice</code> オブジェクトをシステムに追加するには効率的ではありません。 <code class=\"docutils literal notranslate\">Question</code> オブジェクトを追加する時に Choice をひと揃い追加できた方が便利ですよね。そうしてみましょう。</p>\n<p><code class=\"docutils literal notranslate\">Choice</code> モデルに対する <code class=\"docutils literal notranslate\">register()</code> を削除して、 <code class=\"docutils literal notranslate\">Question</code> の登録する部分を以下のように書き換えてください。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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=\"nn\">django.contrib</span> <span class=\"kn\">import</span> admin\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Choice<span class=\"p\">,</span> Question\n\n\n<span class=\"k\">class</span> <span class=\"nc\">ChoiceInline</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>StackedInline<span class=\"p\">):</span>\n    model <span class=\"o\">=</span> Choice\n    extra <span class=\"o\">=</span> <span class=\"mi\">3</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">QuestionAdmin</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>ModelAdmin<span class=\"p\">):</span>\n    fieldsets <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span>               <span class=\"p\">{</span><span class=\"s1\">&#39;fields&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;question_text&#39;</span><span class=\"p\">]}),</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;Date information&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;fields&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">],</span> <span class=\"s1\">&#39;classes&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;collapse&#39;</span><span class=\"p\">]}),</span>\n    <span class=\"p\">]</span>\n    inlines <span class=\"o\">=</span> <span class=\"p\">[</span>ChoiceInline<span class=\"p\">]</span>\n\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>register<span class=\"p\">(</span>Question<span class=\"p\">,</span> QuestionAdmin<span class=\"p\">)</span>\n</code></pre></figure>\n<p>この行は Django に対して、「<code class=\"docutils literal notranslate\">Choice</code> オブジェクトは <code class=\"docutils literal notranslate\">Question</code> の管理ページから編集する。デフォルトでは、 3 つの <code class=\"docutils literal notranslate\">Choice</code> を表示するのに十分なフィールドを用意すること」と指示しています。</p>\n<p>「questionを追加 (Add question)」ページを読み込んで、どのように見えるか確かめてみましょう。</p>\n<img alt=\"Add question page now has choices on it\" src=\"/ja/4.1/_images/admin10t.png\" />\n<p>変わった点をみてみましょう。リレーション相手である <code class=\"docutils literal notranslate\">Choice</code> を表示するために 3 つのスロットがあります (<code class=\"docutils literal notranslate\">extra</code> に指定した数ですね)。また、作成済みのオブジェクトを「編集する」ページに行けば、いつでも 3 つ余分のスロットが表示されるはずです。</p>\n<p>現在の3つのスロットの最後に「別の選択肢を追加」というリンクがあります。 これをクリックすると新しいスロットが追加されます。追加されたスロットを削除したい場合は、追加されたスロットの右上にある×をクリックしてください。この画像は追加されたスロットを示しています:</p>\n<img alt=\"Additional slot added dynamically\" src=\"/ja/4.1/_images/admin14t.png\" />\n<p>しかし、一つだけ小さな問題があります。関連する <code class=\"docutils literal notranslate\">Choice</code> オブジェクトを入力するためのすべてのフィールドを表示するには、多くの画面スペースを必要とします。そのため、Django は関連するオブジェクトをインラインで表示する表形式の方法を提供しています。それを使うには、<code class=\"docutils literal notranslate\">ChoiceInline</code> 宣言を読み替える:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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\">class</span> <span class=\"nc\">ChoiceInline</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>TabularInline<span class=\"p\">):</span>\n    <span class=\"c1\">#...</span>\n</code></pre></figure>\n<p><code class=\"docutils literal notranslate\">StackedInline</code> に代わって <code class=\"docutils literal notranslate\">TabularInline</code> を使うと、 リレーション相手のオブジェクトはコンパクトなテーブル形式で表示されます:</p>\n<img alt=\"Add question page now has more compact choices\" src=\"/ja/4.1/_images/admin11t.png\" />\n<p>Note that there is an extra &quot;Delete?&quot; column that allows removing rows added\nusing the &quot;Add another Choice&quot; button and rows that have already been saved.</p>\n</section>\n<section id=\"customize-the-admin-change-list\">\n<h2>管理サイトのチェンジリストページをカスタマイズする<a class=\"heading-anchor\" href=\"#customize-the-admin-change-list\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>さあ、これで Question の管理ページはだいぶよくなってきました。今度は「チェンジリスト」ページをすこしいじりましょう。チェンジリスト (change list) は、システム上の全ての Question を表示するページです。</p>\n<p>現時点では以下のように表示されています。</p>\n<img alt=\"Polls change list page\" src=\"/ja/4.1/_images/admin04t.png\" />\n<p>デフォルトでは、 Django はオブジェクトの <code class=\"docutils literal notranslate\">str()</code> を表示します。しかし、オブジェクトの各フィールドの値を表示したい場合もあるでしょう。各フィールドの値を表示させるには、 <a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display\" title=\"django.contrib.admin.ModelAdmin.list_display\"><code class=\"xref py py-attr docutils literal notranslate\">list_display</code></a> オプションを使います。このオプションには、カラム表示したいフィールドの名前をタプルにして指定します。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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\">class</span> <span class=\"nc\">QuestionAdmin</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>ModelAdmin<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    list_display <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"s1\">&#39;question_text&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>念のため、 <span class=\"xref std std-doc\">Tutorial 2</span> の was_published_recently() メソッドも含めましょう。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/admin.py</code></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\">class</span> <span class=\"nc\">QuestionAdmin</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>ModelAdmin<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    list_display <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"s1\">&#39;question_text&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;was_published_recently&#39;</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>これで、Question のチェンジリストのページは以下のようになります:</p>\n<img alt=\"Polls change list page, updated\" src=\"/ja/4.1/_images/admin12t.png\" />\n<p>カラムのヘッダをクリックすると、カラムの値に応じてエントリを並べ換えできます。ただし <code class=\"docutils literal notranslate\">was_published_recently</code> ヘッダは例外であり、これはメソッドの戻り値を使った並べ換えをサポートしていないからです。 <code class=\"docutils literal notranslate\">was_published_recently</code> のカラムヘッダは、デフォルトではメソッド名 (アンダースコアを空白に置き換えたもの) になっていることに注目してください。また、各行は戻り値の文字列表現となっています。</p>\n<p>これを改善するには、<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.display\" title=\"django.contrib.admin.display\"><code class=\"xref py py-func docutils literal notranslate\">display()</code></a> デコレータを次のように (<code class=\"file docutils literal notranslate\">polls/models.py</code> の) メソッドに使います:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/models.py</code></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=\"nn\">django.contrib</span> <span class=\"kn\">import</span> admin\n\n<span class=\"k\">class</span> <span class=\"nc\">Question</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"nd\">@admin</span><span class=\"o\">.</span>display<span class=\"p\">(</span>\n        boolean<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n        ordering<span class=\"o\">=</span><span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">,</span>\n        description<span class=\"o\">=</span><span class=\"s1\">&#39;Published recently?&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n    <span class=\"k\">def</span> <span class=\"nf\">was_published_recently</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        now <span class=\"o\">=</span> timezone<span class=\"o\">.</span>now<span class=\"p\">()</span>\n        <span class=\"k\">return</span> now <span class=\"o\">-</span> datetime<span class=\"o\">.</span>timedelta<span class=\"p\">(</span>days<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">&lt;=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>pub_date <span class=\"o\">&lt;=</span> now\n</code></pre></figure>\n<p>デコレータで設定できるプロパティに関する詳しい情報は、<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display\" title=\"django.contrib.admin.ModelAdmin.list_display\"><code class=\"xref py py-attr docutils literal notranslate\">list_display</code></a> を参照してください。</p>\n<p><code class=\"file docutils literal notranslate\">polls/admin.py</code> ファイルをもう一度編集して、<code class=\"docutils literal notranslate\">Question</code> のチェンジリストのページに <a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter\" title=\"django.contrib.admin.ModelAdmin.list_filter\"><code class=\"xref py py-attr docutils literal notranslate\">list_filter</code></a> を追加して、さらに改良しましょう。それには、<code class=\"docutils literal notranslate\">QuestionAdmin</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>list_filter <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>これで、「フィルタ (Filter)」サイドバーができ、チェンジリストを <code class=\"docutils literal notranslate\">pub_date</code> フィールドの値に従ってフィルタできるようになります。</p>\n<img alt=\"Polls change list page, updated\" src=\"/ja/4.1/_images/admin13t.png\" />\n<p>フィルタの種類は、フィルタ対象のフィールドの種類に応じて変化します。<code class=\"docutils literal notranslate\">pub_date</code> は <a class=\"reference internal\" href=\"/ja/4.1/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a> なので、Django はこのフィールドにふさわしいフィルタオプションが、「すべての期間 (&quot;Any date&quot;)」「今日 (&quot;Today&quot;)」「今週 (&quot;Past 7 days&quot;)」「今月 (&quot;This month&quot;)」であることを知っているのです。</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>search_fields <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;question_text&#39;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>これでチェンジリストの上部に検索ボックスが表示されます。ユーザが検索語を入力すると、 Django は <code class=\"docutils literal notranslate\">question_text</code> フィールドを検索します。フィールドはいくらでも使えますが、舞台裏では <code class=\"docutils literal notranslate\">LIKE</code> クエリを使うのでデータベースに過剰な負荷をかけないために常識的な範囲にしましょう。</p>\n<p>さて、ここでお知らせしたいこととして、チェンジリストには最初からページ分割機能があります。デフォルトではページあたり 100 個の要素を表示します。<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_per_page\" title=\"django.contrib.admin.ModelAdmin.list_per_page\"><code class=\"xref py py-attr docutils literal notranslate\">ページ分割</code></a>、<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields\" title=\"django.contrib.admin.ModelAdmin.search_fields\"><code class=\"xref py py-attr docutils literal notranslate\">検索ボックス</code></a>、<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter\" title=\"django.contrib.admin.ModelAdmin.list_filter\"><code class=\"xref py py-attr docutils literal notranslate\">フィルタ</code></a>、<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.date_hierarchy\" title=\"django.contrib.admin.ModelAdmin.date_hierarchy\"><code class=\"xref py py-attr docutils literal notranslate\">日付による階層化</code></a>、<a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display\" title=\"django.contrib.admin.ModelAdmin.list_display\"><code class=\"xref py py-attr docutils literal notranslate\">カラムヘッダを使った並び替え</code></a> の機能は、すべて協調して思いのままに動作します。</p>\n</section>\n<section id=\"customize-the-admin-look-and-feel\">\n<h2>管理サイトのルック &amp; フィールをカスタマイズする<a class=\"heading-anchor\" href=\"#customize-the-admin-look-and-feel\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>管理サイトの上部には「Django 管理 (Django adminstration)」と表示されていますが、これはいささか滑稽ですね。これは単なるプレースホルダテキストにすぎません。</p>\n<p>ただし、Djangoのテンプレートシステムを使用して変更できます。 Django admin はDjango自体を利用しており、そのインターフェースはDjango独自のテンプレートシステムを使用しています。</p>\n<section id=\"customizing-your-project-s-templates\">\n<span id=\"ref-customizing-your-projects-templates\"></span><h3><em>プロジェクト</em> テンプレートをカスタムする。<a class=\"heading-anchor\" href=\"#customizing-your-project-s-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">templates</code> ディレクトリをプロジェクトディレクトリ (<code class=\"docutils literal notranslate\">manage.py</code> が置かれているディレクトリ) に作成してください。テンプレートは Django がアクセスできるファイルシステム内のどこに置いても構いません (アプリケーションサーバーを実行したユーザーでアクセスします)。しかし従うべき慣習として、テンプレートはプロジェクト内に置きましょう。</p>\n<p>設定ファイル (<code class=\"file docutils literal notranslate\">mysite/settings.py</code>) を開いて、<a class=\"reference internal\" href=\"/ja/4.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> 設定オプションの中に、次のように <a class=\"reference internal\" href=\"/ja/4.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> オプションを追加します。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">mysite/settings.py</code></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>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;DIRS&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span>BASE_DIR <span class=\"o\">/</span> <span class=\"s1\">&#39;templates&#39;</span><span class=\"p\">],</span>\n        <span class=\"s1\">&#39;APP_DIRS&#39;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;context_processors&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n                <span class=\"s1\">&#39;django.template.context_processors.debug&#39;</span><span class=\"p\">,</span>\n                <span class=\"s1\">&#39;django.template.context_processors.request&#39;</span><span class=\"p\">,</span>\n                <span class=\"s1\">&#39;django.contrib.auth.context_processors.auth&#39;</span><span class=\"p\">,</span>\n                <span class=\"s1\">&#39;django.contrib.messages.context_processors.messages&#39;</span><span class=\"p\">,</span>\n            <span class=\"p\">],</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p><a class=\"reference internal\" href=\"/ja/4.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> は、Django がテンプレートを読み込む時にチェックする、ファイルシステム上のディレクトリのリストです。サーチパスのようなものです。</p>\n<aside class=\"admonition-organizing-templates admonition\" role=\"note\">\n<p class=\"admonition-title\">テンプレートの構成</p>\n<p>static ファイルと同じように、すべてのテンプレートを1つの大きなテンプレートディレクトリの中に置くことも <em>可能</em> ではあります。しかし、特定のアプリケーションに属するテンプレートは、プロジェクトのテンプレートディレクトリ(<code class=\"docutils literal notranslate\">templates</code>)ではなく、各アプリケーションのテンプレートディレクトリ(例: <code class=\"docutils literal notranslate\">polls/templates</code>)に配置するべきです。 <span class=\"xref std std-doc\">reusable apps tutorial</span> では、どうしてそのようにすべき <em>理由</em> を説明しています。</p>\n</aside>\n<p>さて、<code class=\"docutils literal notranslate\">templates</code> の中に <code class=\"docutils literal notranslate\">admin</code> という名前のディレクトリを作りましょう。Django 自体のソースコード内にある、デフォルトの Django admin テンプレートディレクトリ (<code class=\"docutils literal notranslate\">django/contrib/admin/templates</code>) を探して、 <code class=\"docutils literal notranslate\">admin/base_site.html</code> というテンプレートを、新しく作ったディレクトリにコピーします。</p>\n<aside class=\"admonition-where-are-the-django-source-files admonition\" role=\"note\">\n<p class=\"admonition-title\">Django のソースファイルの場所はどこ？</p>\n<p>Django のソースファイルがシステム中のどこにあるのか分からない場合は、以下のコマンドを実行してください。</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>python -c <span class=\"s2\">&quot;import django; print(django.__path__)&quot;</span>\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</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=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -c <span class=\"s2\">&quot;import django; print(django.__path__)&quot;</span>\n</code></pre></div></div></div>\n</aside>\n<p>そして、ファイルを編集して <code class=\"docutils literal notranslate\">{{ site_header|default:_('Django administration') }}</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=\"cp\">{%</span> <span class=\"k\">block</span> <span class=\"nv\">branding</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;site-name&quot;</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;admin:index&#39;</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>Polls Administration<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endblock</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>このようなアプローチを今使ったのは、テンプレートをオーバーライドする方法を示すためです。実際のプロジェクトで今行ったのと同じカスタマイズを行いたい場合には、 <a class=\"reference internal\" href=\"/ja/4.1/ref/contrib/admin/#django.contrib.admin.AdminSite.site_header\" title=\"django.contrib.admin.AdminSite.site_header\"><code class=\"xref py py-attr docutils literal notranslate\">django.contrib.admin.AdminSite.site_header</code></a> 属性を使えば、もっと簡単に設定できます。</p>\n<p>このテンプレートファイルは <code class=\"docutils literal notranslate\">{% block branding %}</code> や <code class=\"docutils literal notranslate\">{{ title }}</code> のようなテキストを多く含んでいます。 <code class=\"docutils literal notranslate\">{%</code> と <code class=\"docutils literal notranslate\">{{</code> のタグは Django のテンプレート言語の一部です。 <a class=\"reference internal\" href=\"/ja/4.1/intro/tutorial03/\"><span class=\"doc\">チュートリアル その3</span></a> で見たように、Djangoが <code class=\"docutils literal notranslate\">admin/base_site.html</code> をレンダリングする時に、このテンプレート言語が評価され、最終的なHTMLページが生成されます。</p>\n<p>Django のデフォルトのadminテンプレートはすべてオーバーライドできることに注意してください。テンプレートを上書きするには、<code class=\"docutils literal notranslate\">base_site.html</code> で行ったのと同じことをしてください -- デフォルトのディレクトリからカスタムディレクトリにコピーして変更してください。</p>\n</section>\n<section id=\"customizing-your-application-s-templates\">\n<h3><em>アプリケーション用の</em> テンプレートをカスタマイズする<a class=\"heading-anchor\" href=\"#customizing-your-application-s-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>するどい読者はこう質問されるでしょう:  <a class=\"reference internal\" href=\"/ja/4.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a>   はデフォルトで空っぽなのに、 Django はなぜデフォルトの admin テンプレートを見つけることができたのだろう? その答えは <a class=\"reference internal\" href=\"/ja/4.1/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">APP_DIRS</code></a> が <code class=\"docutils literal notranslate\">True</code> に設定されているため、 Django は自動的に各アプリケーションのパッケージのサブディレクトリからフォールバックとして <code class=\"docutils literal notranslate\">templates/</code> を探すからです (<code class=\"docutils literal notranslate\">django.contrib.admin</code> は一つのアプリケーションだということを忘れないでください)。</p>\n<p>投票アプリケーションはそれほど複雑ではないので、カスタムの admin テンプレートは必要ないでしょう。しかしアプリケーションがさらに凝ったものに成長し、何か機能を実現するために標準の admin テンプレートを変更する必要が出てきた場合、 <em>アプリケーションの</em> テンプレートを編集するほうが、 <em>プロジェクト</em> のテンプレートを編集するより賢い選択になるでしょう。そうすれば、投票アプリケーションを他のどの新しいプロジェクトにも追加でき、投票アプリケーションが（自分自身に必要な）カスタムテンプレートを確実に見つけることができます。</p>\n<p>Django のテンプレートの検索方法に関する詳しい情報は、<a class=\"reference internal\" href=\"/ja/4.1/topics/templates/#template-loading\"><span class=\"std std-ref\">テンプレート読み込み ドキュメント</span></a> を参照してください。</p>\n</section>\n</section>\n<section id=\"customize-the-admin-index-page\">\n<h2>admin index ページをカスタムする<a class=\"heading-anchor\" href=\"#customize-the-admin-index-page\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>近い話題として、 Django の admin index ページのルックアンドフィールをカスタマイズもできます。</p>\n<p>デフォルトでは、 admin アプリケーションで登録された <a class=\"reference internal\" href=\"/ja/4.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> のすべてのアプリケーションが、アルファベット順に表示されます。レイアウトを大きく変更したい場合もあるでしょう。なんといっても、index ページは admin の中でおそらく最も重要なページなので、使いやすいほうがいいですからね。</p>\n<p>カスタマイズ対象のテンプレートは <code class=\"docutils literal notranslate\">admin/index.html</code> です。 (前セクションで <code class=\"docutils literal notranslate\">admin/base_site.html</code> にしたことと同じことをしてください。つまり、デフォルトのディレクトリからコピーして、カスタムテンプレートのディレクトリに配置してください)。編集してみると <code class=\"docutils literal notranslate\">app_list</code> というテンプレート変数が使われているのがわかるでしょう。この変数にはインストールされた全 Django アプリが含まれています。これを使う代わりに、各オブジェクトの admin ページヘのリンクをハードコードし、好きなようにカスタマイズできます。</p>\n</section>\n<section id=\"what-s-next\">\n<h2>次は何をしましょうか？<a class=\"heading-anchor\" href=\"#what-s-next\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>これで、初めての人のためのチュートリアルはおしまいです。<a class=\"reference internal\" href=\"/ja/4.1/intro/whatsnext/\"><span class=\"doc\">次のステップへ</span></a> では、ここから進める場所について説明しています。</p>\n<p>Python のパッケージングについて知っていて、polls アプリケーションを「再利用可能なアプリケーション」へと変える方法について学びたい場合は、<a class=\"reference internal\" href=\"/ja/4.1/intro/reusable-apps/\"><span class=\"doc\">チュートリアル 応用編: 再利用可能なアプリケーションの書き方</span></a> を読んでみてください。</p>\n</section>","rootId":"writing-your-first-django-app-part-7","toc":[{"title":"admin フォームのカスタマイズ","anchor":"customize-the-admin-form","children":[]},{"title":"リレーションを張ったオブジェクトの追加","anchor":"adding-related-objects","children":[]},{"title":"管理サイトのチェンジリストページをカスタマイズする","anchor":"customize-the-admin-change-list","children":[]},{"title":"管理サイトのルック & フィールをカスタマイズする","anchor":"customize-the-admin-look-and-feel","children":[{"title":"プロジェクト テンプレートをカスタムする。","anchor":"customizing-your-project-s-templates","children":[]},{"title":"アプリケーション用の テンプレートをカスタマイズする","anchor":"customizing-your-application-s-templates","children":[]}]},{"title":"admin index ページをカスタムする","anchor":"customize-the-admin-index-page","children":[]},{"title":"次は何をしましょうか？","anchor":"what-s-next","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"さぁ始めましょう","url":"/ja/4.1/intro/"}],"prev":{"docname":"intro/tutorial06","title":"はじめての Django アプリ作成、その 6","url":"/ja/4.1/intro/tutorial06/"},"next":{"docname":"intro/reusable-apps","title":"高度なチュートリアル: 再利用可能アプリの書き方","url":"/ja/4.1/intro/reusable-apps/"},"formats":{"html":"/ja/4.1/intro/tutorial07/","markdown":"/ja/4.1/intro/tutorial07.md","json":"/ja/4.1/intro/tutorial07.json"},"source":"https://github.com/django/django/blob/stable/4.1.x/docs/intro/tutorial07.txt","official":"https://docs.djangoproject.com/ja/4.1/intro/tutorial07/","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","it","pt-br","ko","es","el","pl"]}