{"title":"첫 번째 장고 앱 작성하기, part 7","version":"4.1","locale":"ko","docname":"intro/tutorial07","url":"/ko/4.1/intro/tutorial07/","canonical":"https://djangodocs.dev/ko/4.1/intro/tutorial07/","summary":"이 튜토리얼은 튜토리얼 6장 에 이어서 시작합니다. 우리는 웹 설문조사 어플리케이션을 계속 다루고 있으며, Tutorial 2 에서 봤었던 자동으로 생성된 관리자…","html":"<h1>첫 번째 장고 앱 작성하기, part 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>이 튜토리얼은 <a class=\"reference internal\" href=\"/ko/4.1/intro/tutorial06/\"><span class=\"doc\">튜토리얼 6장</span></a> 에 이어서 시작합니다. 우리는 웹 설문조사 어플리케이션을 계속 다루고 있으며, <a class=\"reference internal\" href=\"/ko/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 섹션인 :doc:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>Getting Help &lt;/faq/help&gt;`으로 이동하십시오.</p>\n</aside>\n<section id=\"customize-the-admin-form\">\n<h2>관리자 폼 커스터마이징<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\">Question</code> 모델을 <code class=\"docutils literal notranslate\">admin.site.register(Question)</code>에 등록함으로써, Django는 디폴트 폼 표현을 구성 할 수 있었습니다. 관리 폼이 보이고 작동하는 방법을 커스터마이징하려는 경우가 있습니다. 객체를 등록 할 때 Django에 원하는 옵션을 알려주면 커스터마이징 할 수 있습니다.</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>모델의 관리자 옵션을 변경해야 할 때마다 이 패턴 – 모델 어드민 클래스를 만든 다음, <code class=\"docutils literal notranslate\">admin.site.register()</code>에 두 번째 인수로 전달합니다 – 을 따라하면 됩니다.</p>\n<p>여기서 특별한 변경 사항은 “발행일”이 “설문” 필드 앞에 오게 만듭니다.</p>\n<img alt=\"Fields have been reordered\" src=\"/ko/4.1/_images/admin07.png\" />\n<p>단지 2개의 필드만으로는 인상적이지는 않지만, 수십 개의 필드가 있는 관리 폼의 경우에는 직관적인 순서을 선택하는 것이 사용 편리성의 중요한 부분입니다.</p>\n<p>수십 개의 필드가 있는 폼에 관해서는 폼을 fieldset으로 분할하는 것이 좋습니다.</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=\"/ko/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>의 각 튜플의 첫 번째 요소는 fieldset의 제목입니다. 우리의 폼이 다음과 같이 변했네요.</p>\n<img alt=\"Form has fieldsets now\" src=\"/ko/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>들을 가지고 있음에도, admin 페이지는 선택 사항을 표시하지 않습니다.</p>\n<p>아직까진 말이죠.</p>\n<p>이 문제를 해결하는 방법은 두 가지가 있습니다. 첫 번째는 <code class=\"docutils literal notranslate\">Question</code>:과 마찬가지로 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>Choice``를 관리자에 등록하는 것입니다.</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>이제 “Choices”는 Django 관리자가 사용할 수 있는 옵션입니다. “Add choice” 폼은 다음과 같습니다.</p>\n<img alt=\"Choice admin page\" src=\"/ko/4.1/_images/admin09.png\" />\n<p>이 양식에서 “Question” 필드는 데이터베이스의 모든 질문을 포함하는 select box입니다. Django는 <a class=\"reference internal\" href=\"/ko/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>가 admin에서 <code class=\"docutils literal notranslate\">&lt;select&gt;</code>로 표현되어야 함을 알고 있습니다. 우리의 경우, 지금은 단 하나의 질문만이 존재합니다.</p>\n<p>Also note the “Add another question” link next to “Question.” Every object with\na <code class=\"docutils literal notranslate\">ForeignKey</code> relationship to another gets this for free. When you click\n“Add another question”, you’ll get a popup window with the “Add question” form.\nIf you add a question in that window and click “Save”, Django will save the\nquestion to the database and dynamically add it as the selected choice on the\n“Add choice” form you’re looking at.</p>\n<p>그러나 실제로 이것은 <code class=\"docutils literal notranslate\">Choice</code> 객체를 시스템에 추가하는 비효율적인 방법입니다. <code class=\"docutils literal notranslate\">Question</code> 객체를 생성할 때 여러 개의 Choices를 직접 추가할 수 있다면 더 좋을 것입니다. 그것을 만들어 봅시다.</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가지 선택 항목을 제공함.” 이라고 알려줍니다.</p>\n<p>모양을 보려면 “Add question” 페이지를 로드하십시오.</p>\n<img alt=\"Add question page now has choices on it\" src=\"/ko/4.1/_images/admin10t.png\" />\n<p>이 화면은 다음과 같이 작동합니다. 관련된 선택 사항을 위한 슬롯이 세 개 있으며– <code class=\"docutils literal notranslate\">extra</code>로 지정됨 – 이미 생성된 객체의 “Change” 페이지의 경우에도 빈 세 개의 슬롯이 생깁니다.</p>\n<p>세 개의 현재 슬롯 끝에 “Add another Choice” 링크가 있습니다. 클릭하면 새로운 슬롯이 추가됩니다. 추가된 슬롯을 제거하려면 추가된 슬롯의 오른쪽 상단에 있는 X를 누르면 됩니다. 이 이미지에는 추가된 슬롯이 표시됩니다.</p>\n<img alt=\"Additional slot added dynamically\" src=\"/ko/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=\"/ko/4.1/_images/admin11t.png\" />\n<p>Note that there is an extra “Delete?” column that allows removing rows added\nusing the “Add another Choice” button and rows that have already been saved.</p>\n</section>\n<section id=\"customize-the-admin-change-list\">\n<h2>관리자 변경 목록(change list) 커스터마이징<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>이제 질문 관리 페이지가 괜찮아 보이므로, 시스템의 모든 질문을 표시하는 “변경 목록” 페이지를 약간 조정하십시오.</p>\n<p>다음은 이 시점의 모습입니다.</p>\n<img alt=\"Polls change list page\" src=\"/ko/4.1/_images/admin04t.png\" />\n<p>기본적으로 Django는 각 객체의 <code class=\"docutils literal notranslate\">str()</code>을 표시합니다. 그러나 개별 필드를 표시 할 수 있는 경우 가끔 도움이 될 수 있습니다. 이렇게 하려면 <a class=\"reference internal\" href=\"/ko/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> admin 옵션을 사용합니다. 이 옵션은 객체의 변경 목록 페이지에서 열로 표시 할 필드 이름들의 튜플입니다.</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>좋은 측정을 위해 <a class=\"reference internal\" href=\"/ko/4.1/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a>:의 <code class=\"docutils literal notranslate\">was_published_recently()</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\">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>이제 질문 변경 목록 페이지는 다음과 같습니다.</p>\n<img alt=\"Polls change list page, updated\" src=\"/ko/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=\"/ko/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> decorator를 해당 메서드( :file:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>polls/models.py`에 있는)에 사용하면 다음과 같이 개선할 수 있습니다.</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>Decorator를 통해 구성할 수 있는 속성에 대한 자세한 내용은 :attr:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>~django.contrib.admin.ModelAdmin.list_display`을 참조하십시오.</p>\n<p><code class=\"file docutils literal notranslate\">polls/admin.py</code> 파일을 다시 편집하고 Question  변경 목록 페이지에 개선점을 추가하십시오: <a class=\"reference internal\" href=\"/ko/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><code class=\"docutils literal notranslate\">pub_date</code> 필드에 의해 사람들이 변경 목록을 필터링 할 수 있게 해주는 “Filter” 사이드 바가 추가되었습니다:</p>\n<img alt=\"Polls change list page, updated\" src=\"/ko/4.1/_images/admin13t.png\" />\n<p>표시되는 필터의 유형은 필터링중인 필드의 유형에 따라 다릅니다. <code class=\"docutils literal notranslate\">pub_date</code>는 <a class=\"reference internal\" href=\"/ko/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는 “Any date”, “Today”, “Past 7 days”, “This month”, “This year” 등의 적절한 필터 옵션을 제공합니다.</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>그러면 변경 목록 맨 위에 검색 창이 추가됩니다. 누군가가 검색어를 입력하면, 장고는 <code class=\"docutils literal notranslate\">question_text</code> 필드를 검색합니다. 당신이 원하는 만큼의 필드를 사용할 수 있습니다 – 그것은 내부적으로 <code class=\"docutils literal notranslate\">LIKE</code> 쿼리를 사용하기 때문에 검색 필드의 수를 적당한 수로 제한하면 데이터베이스가 검색을 더 쉽게 할 수 있습니다.</p>\n<p>이제 변경 목록이 자동 페이징 기능을 제공한다는 점을 기억하십시오. 기본값은 페이지 당 100 개의 항목을 표시하는 것입니다. <a class=\"reference internal\" href=\"/ko/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=\"/ko/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=\"/ko/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=\"/ko/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=\"/ko/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>관리자 룩앤필 커스터마이징<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 administration”이 있다는 것은 우스꽝스럽습니다. 이건 그저 자리를 채워넣기 위한 문자열입니다.</p>\n<p>그러나 Django의 템플릿 시스템을 사용하여 변경할 수 있습니다. Django 관리자는 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\">manage.py</code>를 포함하고있는)에 <code class=\"docutils literal notranslate\">templates</code> 디렉토리를 만듭니다. 템플릿은 장고가 액세스 할 수있는 파일 시스템 어디에서나 사용할 수 있습니다. (Django는 서버가 실행되는 사용자로 실행됩니다.) 그러나 프로젝트 내에 템플릿을 유지하는 것은 따라야 할 좋은 규칙입니다.</p>\n<p>설정 파일 (<code class=\"file docutils literal notranslate\">mysite/settings.py</code>를 기억하세요)을 열고 <a class=\"reference internal\" href=\"/ko/4.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> 옵션을 <a class=\"reference internal\" href=\"/ko/4.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</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=\"/ko/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>정적 파일과 마찬가지로, 하나의 커다란 템플릿 디렉토리에 모든 템플릿을 함께 넣을 수 있습니다. 그렇게 해도 완벽하게 잘 작동할 것입니다. 그러나, 특정 애플리케이션에 속한 템플릿은 프로젝트(<code class=\"docutils literal notranslate\">templates</code>) 가 아닌 해당 애플리케이션의 템플릿 디렉토리(예: <code class=\"docutils literal notranslate\">polls/templates</code>)에 있어야 합니다. 우리는 왜 우리가 이렇게 해야하는 지에 대한 더 자세한 내용을 <a class=\"reference internal\" href=\"/ko/4.1/intro/reusable-apps/\"><span class=\"doc\">reusable apps tutorial</span></a> 에서 논의할 것입니다.</p>\n</aside>\n<p>이제 <code class=\"docutils literal notranslate\">templates</code> 디렉토리에 <code class=\"docutils literal notranslate\">admin</code>이라는 디렉토리를 만들고 장고 소스 코드 디렉토리(<code class=\"docutils literal notranslate\">django/contrib/admin/templates</code>) 에 기본 관리자 템플릿 디렉토리 안에 있는 admin/base_site.html` 템플릿을 방금 만든 디렉토리로 복사합니다.</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=\"/ko/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가 <code class=\"docutils literal notranslate\">admin/base_site.html</code>을 렌더링 할 때, 이 템플릿 언어는 <a class=\"reference internal\" href=\"/ko/4.1/intro/tutorial03/\"><span class=\"doc\">튜토리얼 3장</span></a>에서 보았 듯이 최종 HTML 페이지를 생성하기 위해 평가 될 것입니다.</p>\n<p>Django의 기본 관리 템플릿은 재정의할 수 있습니다. 템플릿을 재정의하려면 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>base_site.html``에서 수행한 작업을 동일하게 수행하십시오. 즉, 기본 디렉토리에서 사용자 지정 디렉토리로 복사한 후 변경하십시오.</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=\"/ko/4.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a>가 기본설정으로 비어 있다면, 장고는 기본 관리자 템플릿을 어떻게 찾을까요? 그 해답은 <a class=\"reference internal\" href=\"/ko/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 템플릿이 필요하지 않습니다. 그러나 Django의 표준 admin 템플릿을 좀더 정교하게 필요에 맞게 수정 할 경우 <em>프로젝트</em> 템플릿 대신 <em>어플리케이션</em>의 템플릿을 수정하는 것이 더 현명합니다. 그렇게 하면 다른 새 프로젝트에 투표 애플리케이션을 포함시킬 수 있고, 필요할때는 커스텀 템플릿을 찾을수 있습니다.</p>\n<p>Django가 템플릿을 찾는 방법에 대한 자세한 정보는 <a class=\"reference internal\" href=\"/ko/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 인덱스 페이지 수정하기<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 인덱스 페이지의 모양과 느낌을 수정하고 싶을 수도 있습니다.</p>\n<p>기본적으로 admin 어플리케이션과 함께 등록된 <a class=\"reference internal\" href=\"/ko/4.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a>의 모든 어플리케이션을 사전순으로 표시합니다. 어쩌면 레이아웃을 크게 변경하고자 할 수 있습니다. 설사 그렇게 하더라도 인덱스는 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>라는 템플릿 변수를 사용하는 것을 볼 수 있습니다. 이 변수는 설치된 모든 장고 앱을 포함합니다. 이를 사용하는 대신 최선의 방법이라고 생각한다면  개체 별 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=\"/ko/4.1/intro/whatsnext/\"><span class=\"doc\">앞으로 무엇을 해야할 지</span></a> 문서를 좀 더 읽어볼 수 있습니다.</p>\n<p>파이썬 패키징에 익숙하고 설문 조사를 “재사용 가능한 앱”으로 바꾸는 방법을 배우고 싶다면 <a class=\"reference internal\" href=\"/ko/4.1/intro/reusable-apps/\"><span class=\"doc\">심화 튜토리얼:재사용 가능한 애플리케이션을 만드는 법</span></a>을 읽어보십시오.</p>\n</section>","rootId":"writing-your-first-django-app-part-7","toc":[{"title":"관리자 폼 커스터마이징","anchor":"customize-the-admin-form","children":[]},{"title":"관련된 객체 추가","anchor":"adding-related-objects","children":[]},{"title":"관리자 변경 목록(change list) 커스터마이징","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 인덱스 페이지 수정하기","anchor":"customize-the-admin-index-page","children":[]},{"title":"다음 내용은?","anchor":"what-s-next","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"시작하기","url":"/ko/4.1/intro/"}],"prev":{"docname":"intro/tutorial06","title":"첫 번째 장고 앱 작성하기, part 6","url":"/ko/4.1/intro/tutorial06/"},"next":{"docname":"intro/reusable-apps","title":"심화 튜토리얼: 재사용 가능한 앱을 만드는 법","url":"/ko/4.1/intro/reusable-apps/"},"formats":{"html":"/ko/4.1/intro/tutorial07/","markdown":"/ko/4.1/intro/tutorial07.md","json":"/ko/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/ko/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"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}