{"title":"Escrevendo seu primeiro app Django, parte 7","version":"6.1","locale":"pt-br","docname":"intro/tutorial07","url":"/pt-br/6.1/intro/tutorial07/","canonical":"https://djangodocs.dev/pt-br/6.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>Escrevendo seu primeiro app Django, parte 7<a class=\"heading-anchor\" href=\"#writing-your-first-django-app-part-7\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>This tutorial begins where <a class=\"reference internal\" href=\"/pt-br/6.1/intro/tutorial06/\"><span class=\"doc\">Tutorial 6</span></a> left off.\nWe’re continuing the web-poll application and will focus on customizing\nDjango’s automatically-generated admin site that we first explored in\n<a class=\"reference internal\" href=\"/pt-br/6.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\">Onde obter ajuda:</p>\n<p>Se tiver problemas enquanto caminha por este tutorial, por favor consulte a seção <a class=\"reference internal\" href=\"/pt-br/6.1/faq/help/\"><span class=\"doc\">Obtendo ajuda</span></a> da FAQ.</p>\n</aside>\n<section id=\"customize-the-admin-form\">\n<h2>Personalize o formulário do site de administração<a class=\"heading-anchor\" href=\"#customize-the-admin-form\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ao registrarmos o modelo de <code class=\"docutils literal notranslate\">Question``através da linha ``admin.site.register(Question)</code>, o Django constrói um formulário padrão para representá-lo. Comumente, você desejará personalizar a apresentação e o funcionamento dos formulários do site de administração do Django. Para isto, você precisará informar ao Django as opções que você quer utilizar ao registrar o seu modelo.</p>\n<p>Vamos ver como isto funciona reordenando os campos no formulário de edição. Substitua a linha àdmin.site.register(Question)` por:</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=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;question_text&quot;</span><span class=\"p\">]</span>\n\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>Você seguirá este padrão – crie uma classe de “model admin”, em seguida, passe-a como o segundo argumento para o <code class=\"docutils literal notranslate\">admin.site.register()</code> – todas as vezes que precisar alterar as opções administrativas para um modelo.</p>\n<p>Essa mudança específica no código acima faz com que a “Publication date” apareça antes do campo “Question”:</p>\n<img alt=\"Fields have been reordered\" src=\"/pt-br/6.1/_images/admin07.png\" />\n<p>Isso não é impressionante com apenas dois campos, mas para formulários com dúzias deles, escolher uma ordem intuitiva é um detalhe importante para a usabilidade.</p>\n<p>E por falar em dúzias de campos, você pode querer dividir o formulário em grupos:</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=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;question_text&quot;</span><span class=\"p\">]}),</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;Date information&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">]}),</span>\n    <span class=\"p\">]</span>\n\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>O primeiro elemento de cada tupla em <a class=\"reference internal\" href=\"/pt-br/6.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> é o título do grupo. Aqui está como o nosso formulário se parece agora:</p>\n<img alt=\"Form has fieldsets now\" src=\"/pt-br/6.1/_images/admin08t.png\" />\n</section>\n<section id=\"adding-related-objects\">\n<h2>Adicionando objetos relacionados<a class=\"heading-anchor\" href=\"#adding-related-objects\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ok, nós temos nossa página de administração Questão, mas a <code class=\"docutils literal notranslate\">Questão</code> tem múltiplas <code class=\"docutils literal notranslate\">Questõe</code>s, e a página de administração não exibe escolhas.</p>\n<p>Ainda.</p>\n<p>There are two ways to solve this problem. The first is to register <code class=\"docutils literal notranslate\">Choice</code>\nwith the admin just as we did with <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<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>Agora “Choices” é uma opção disponível no site de administração do Django. O formulário de “Add choice” se parece com isto:</p>\n<img alt=\"Choice admin page\" src=\"/pt-br/6.1/_images/admin09.png\" />\n<p>Nesse formulário, o campo “Question” é uma caixa de seleção contendo todas as enquetes no banco de dados. O Django sabe que uma <a class=\"reference internal\" href=\"/pt-br/6.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> deve ser representada no site de administração como um campo <code class=\"docutils literal notranslate\">&lt;select&gt;</code>. No nosso caso, só existe uma enquete até agora.</p>\n<p>Also note the “Add another question” button (displayed as a plus sign) to the\nright of the “Question” field. Every <code class=\"docutils literal notranslate\">ForeignKey</code> relationship gets this\nbutton for free. When you click this button, you’ll get a popup window with the\n“Add question” form. If you add a question in that window and click “Save”,\nDjango will save the question to the database and dynamically add it as the\nselected choice on the “Add choice” form you’re looking at.</p>\n<p>Mas, sério, essa é uma maneira ineficiente de adicionar objetos <code class=\"docutils literal notranslate\">Choice</code> ao sistema. Seria muito melhor se você pudesse adicionar várias opções diretamente quando criasse um objeto <code class=\"docutils literal notranslate\">Question</code>. Vamos fazer isso acontecer.</p>\n<p>Remova a chamada <code class=\"docutils literal notranslate\">register()</code> do modelo <code class=\"docutils literal notranslate\">Choice</code>. Então edite o código de registro de <code class=\"docutils literal notranslate\">Question</code> para que fique assim:</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=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;question_text&quot;</span><span class=\"p\">]}),</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;Date information&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">],</span> <span class=\"s2\">&quot;classes&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;collapse&quot;</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\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>Isso informa ao Django: Objetos “<code class=\"docutils literal notranslate\">Choice</code> são editados na mesma página de administração de <code class=\"docutils literal notranslate\">Question</code>. Por padrão, forneça campos suficientes para 3 escolhas.”</p>\n<p>Carregue a página “Add question” para ver como está:</p>\n<img alt=\"Add question page now has choices on it\" src=\"/pt-br/6.1/_images/admin10t.png\" />\n<p>Funciona assim: há três blocos para Escolhas relacionadas – como especificado em <code class=\"docutils literal notranslate\">extra</code> –, mas a cada vez que você retorna à página de “Alteração” para um objeto já criado, você ganha outros três blocos extra.</p>\n<p>At the end of the three current slots you will find an “Add another Choice”\nlink. If you click on it, a new slot will be added. If you want to remove the\nadded slot, you can click on the X to the top right of the added slot. This\nimage shows an added slot:</p>\n<img alt=\"Additional slot added dynamically\" src=\"/pt-br/6.1/_images/admin14t.png\" />\n<p>One small problem, though. It takes a lot of screen space to display all the\nfields for entering related <code class=\"docutils literal notranslate\">Choice</code> objects. For that reason, Django offers\na tabular way of displaying inline related objects. To use it, change the\n<code class=\"docutils literal notranslate\">ChoiceInline</code> declaration to read:</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> <span class=\"o\">...</span>\n</code></pre></figure>\n<p>Com o <code class=\"docutils literal notranslate\">TabularInline</code> (em vez de <code class=\"docutils literal notranslate\">StackedInline</code>), os objetos relacionados são exibidos de uma maneira mais compacta, formatada em tabela:</p>\n<img alt=\"Add question page now has more compact choices\" src=\"/pt-br/6.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>Personalize a listagem da página de administração<a class=\"heading-anchor\" href=\"#customize-the-admin-change-list\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Agora que a página de administração de Pergunta está bonita, vamos fazer algumas melhorias à página “change list” – aquela que exibe todas as enquetes do sistema.</p>\n<p>Aqui é como ela está até agora:</p>\n<img alt=\"Polls change list page\" src=\"/pt-br/6.1/_images/admin04t.png\" />\n<p>By default, Django displays the <code class=\"docutils literal notranslate\">str()</code> of each object. But sometimes it’d be\nmore helpful if we could display individual fields. To do that, use the\n<a class=\"reference internal\" href=\"/pt-br/6.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 option, which is a\nlist of field names to display, as columns, on the change list page for the\nobject:</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=\"s2\">&quot;question_text&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">]</span>\n</code></pre></figure>\n<p>For good measure, let’s also include the <code class=\"docutils literal notranslate\">was_published_recently()</code> method\nfrom <a class=\"reference internal\" href=\"/pt-br/6.1/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></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=\"s2\">&quot;question_text&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;was_published_recently&quot;</span><span class=\"p\">]</span>\n</code></pre></figure>\n<p>Agora a página de edição de enquetes está assim:</p>\n<img alt=\"Polls change list page, updated\" src=\"/pt-br/6.1/_images/admin12t.png\" />\n<p>Você pode clicar no cabeçalho da coluna para ordená-las por estes valores – exceto no caso do <code class=\"docutils literal notranslate\">was_published_recently</code>, porque a ordenação pelo resultado de um método arbitrário não é suportada. Também note que o cabeçalho da coluna\npara <code class=\"docutils literal notranslate\">was_published_recently</code> é, por padrão, o nome do método (com underscores substituídos por espaços), e que cada linha contem a representação da saída.</p>\n<p>You can improve that by using the <a class=\"reference internal\" href=\"/pt-br/6.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>\ndecorator on that method (extending the <code class=\"file docutils literal notranslate\">polls/models.py</code> file that was\ncreated in <a class=\"reference internal\" href=\"/pt-br/6.1/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a>), as follows:</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\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=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">,</span>\n        description<span class=\"o\">=</span><span class=\"s2\">&quot;Published recently?&quot;</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>For more information on the properties configurable via the decorator, see\n<a class=\"reference internal\" href=\"/pt-br/6.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>Edite o arquivo <code class=\"file docutils literal notranslate\">polls/admin.py</code> de novo e adicione uma melhoria à  página de lista de edição <code class=\"docutils literal notranslate\">Question</code>: Um filtro usando <a class=\"reference internal\" href=\"/pt-br/6.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>. Adicione a seguinte linha ao <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=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>Isso adiciona uma barra lateral “Filter” que permite às pessoas filtrarem a lista de edição pelo campo <code class=\"docutils literal notranslate\">pub_date</code>:</p>\n<img alt=\"Polls change list page, updated\" src=\"/pt-br/6.1/_images/admin13t.png\" />\n<p>O tipo do filtro apresentado depende do tipo do campo pelo qual você está filtrando. Como <code class=\"docutils literal notranslate\">pub_date</code> é uma instância da classe  <a class=\"reference internal\" href=\"/pt-br/6.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>, o Django consegue deduzir que os filtros apropriados são: “Qualquer data”, “Hoje”, “Últimos 7 dias”, “Esse mês”, “Esse ano”.</p>\n<p>Isso está ficando bom. Vamos adicionar capacidade de pesquisa:</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=\"s2\">&quot;question_text&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>Isso adiciona um campo de pesquisa ao topo da lista de edição. Quando alguém informa termos de pesquisa, o Django irá pesquisar o campo <code class=\"docutils literal notranslate\">question_text</code>. Você pode usar quantos campos quiser – entretanto, por ele usar uma consulta <code class=\"docutils literal notranslate\">LIKE</code> internamente, limitar o número de campos de pesquisa a um número razoável, será mais fácil para o seu banco de dados para fazer pesquisas.</p>\n<p>Now’s also a good time to note that change lists give you free pagination. The\ndefault is to display 100 items per page.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">Ver também</p>\n<p>The following <a class=\"reference internal\" href=\"/pt-br/6.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin\" title=\"django.contrib.admin.ModelAdmin\"><code class=\"xref py py-class docutils literal notranslate\">ModelAdmin</code></a> options allow\nfurther customization of change lists:\n<a class=\"reference internal\" href=\"/pt-br/6.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\">list_per_page</code></a>,\n<a class=\"reference internal\" href=\"/pt-br/6.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\">search_fields</code></a>,\n<a class=\"reference internal\" href=\"/pt-br/6.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\">date_hierarchy</code></a>, and\n<a class=\"reference internal\" href=\"/pt-br/6.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</aside>\n</section>\n<section id=\"customize-the-admin-look-and-feel\">\n<h2>Personalize a aparência do site de administração<a class=\"heading-anchor\" href=\"#customize-the-admin-look-and-feel\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Obviamente, ter “Django administration” no topo de cada página de administração é ridículo. Isso é só um texto de exemplo.</p>\n<p>You can change it, though, using Django’s template system. The Django admin is\npowered by Django itself, and its interfaces use Django’s own template system.</p>\n<section id=\"customizing-your-project-s-templates\">\n<span id=\"ref-customizing-your-projects-templates\"></span><h3>Personalize os templates do seu <em>projeto</em><a class=\"heading-anchor\" href=\"#customizing-your-project-s-templates\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Create a <code class=\"docutils literal notranslate\">templates</code> directory in your <code class=\"docutils literal notranslate\">djangotutorial</code> directory.\nTemplates can live anywhere on your filesystem that Django can access. (Django\nruns as whatever user your server runs.) However, keeping your templates within\nthe project is a good convention to follow.</p>\n<p>Abra seu arquivo de configurações (<code class=\"file docutils literal notranslate\">mysite/settings.py</code>, lembre-se) e adicione uma opção  <a class=\"reference internal\" href=\"/pt-br/6.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a>. na configuração <a class=\"reference internal\" href=\"/pt-br/6.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> setting:</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=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;DIRS&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>BASE_DIR <span class=\"o\">/</span> <span class=\"s2\">&quot;templates&quot;</span><span class=\"p\">],</span>\n        <span class=\"s2\">&quot;APP_DIRS&quot;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;OPTIONS&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;context_processors&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n                <span class=\"s2\">&quot;django.template.context_processors.request&quot;</span><span class=\"p\">,</span>\n                <span class=\"s2\">&quot;django.contrib.auth.context_processors.auth&quot;</span><span class=\"p\">,</span>\n                <span class=\"s2\">&quot;django.contrib.messages.context_processors.messages&quot;</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=\"/pt-br/6.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> é uma lista de diretórios de arquivos que serão checados quando o Django carregar seus templates, ou seja, caminhos de busca.</p>\n<aside class=\"admonition-organizing-templates admonition\" role=\"note\">\n<p class=\"admonition-title\">Organizando templates</p>\n<p>Just like the static files, we <em>could</em> have all our templates together, in\none big templates directory, and it would work perfectly well. However,\ntemplates that belong to a particular application should be placed in that\napplication’s template directory (e.g. <code class=\"docutils literal notranslate\">polls/templates</code>) rather than the\nproject’s (<code class=\"docutils literal notranslate\">templates</code>). We’ll discuss in more detail in the\n<a class=\"reference internal\" href=\"/pt-br/6.1/intro/reusable-apps/\"><span class=\"doc\">reusable apps tutorial</span></a> <em>why</em> we do this.</p>\n</aside>\n<p>Now create a directory called <code class=\"docutils literal notranslate\">admin</code> inside <code class=\"docutils literal notranslate\">templates</code>, and copy the\ntemplate <code class=\"docutils literal notranslate\">admin/base_site.html</code> from within the default Django admin\ntemplate directory in the source code of Django itself\n(<a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/6.1.x/django/contrib/admin/templates\">django/contrib/admin/templates</a>) into that directory.</p>\n<aside class=\"admonition-where-are-the-django-source-files admonition\" role=\"note\">\n<p class=\"admonition-title\">Onde estão os arquivos de código-fonte do Django?</p>\n<p>Se você tiver dificuldade em encontrar onde os arquivos do Django estão localizados em seu sistema, execute o seguinte comando:</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>Então, edite o arquivo e substitua <code class=\"docutils literal notranslate\">{{ site_header|default:_('Django administration') }}</code> (incluindo as chaves) com nome do seu próprio site como desejar. Você deve acabar com uma secção de código como:</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\">div</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\">div</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">user.is_anonymous</span> <span class=\"cp\">%}</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">include</span> <span class=\"s2\">&quot;admin/color_theme_toggle.html&quot;</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endblock</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Nós usamos esta abordagem para ensinar-lhe como substituir templates. Em um projeto real, você provavelmente usaria o atributo <a class=\"reference internal\" href=\"/pt-br/6.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> para fazer mais facilmente essa personalização em particular.</p>\n<p>Esse template contém uma série de textos como <code class=\"docutils literal notranslate\">{% block branding %}</code> e <code class=\"docutils literal notranslate\">{{ tittle }}</code>. As tags <code class=\"docutils literal notranslate\">{%</code> e <code class=\"docutils literal notranslate\">{{</code> fazem pate da linguagem de templates do Django. Quando o Django renderiza o template “admin/base_site.html”, o seu conteúdo é processado por essa linguagem de templates para produzir a página HTML final, assim como vimos no <a class=\"reference internal\" href=\"/pt-br/6.1/intro/tutorial03/\"><span class=\"doc\">Tutorial 3</span></a>.</p>\n<p>Note que qualquer template padrão do site de administração pode ser sobrescrito. Para sobrescrever um template, apenas faça a mesma coisa que você fez com <code class=\"docutils literal notranslate\">base_site.html</code> – copie ele do diretório padrão para o seu próprio diretório, e faça as mudanças.</p>\n</section>\n<section id=\"customizing-your-application-s-templates\">\n<h3>Personalize os templates da sua <em>aplicação</em><a class=\"heading-anchor\" href=\"#customizing-your-application-s-templates\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Leitores astutos irão se perguntar: Mas se <a class=\"reference internal\" href=\"/pt-br/6.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> estava vazio por padrão, como o Django pôde encontrar o diretório padrão dos templates do site de administração? A resposta é, Desde que <a class=\"reference internal\" href=\"/pt-br/6.1/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">APP_DIRS</code></a> seja <code class=\"docutils literal notranslate\">True</code>, o Django irá automaticamente procurar por um subdiretório <code class=\"docutils literal notranslate\">templates/</code> dentro de cada pacote de aplicação, para usar como fallback(Não esqueça que <code class=\"docutils literal notranslate\">django.contrib.admin</code> é uma aplicação)</p>\n<p>Nossa aplicação de enquetes não é muito complexa e não precisa de templates personalizados para o site de administração. Mas se ele crescer e ficar mais sofisticado e necessária a modificação dos templates padrão de administração do Django para algumas de suas funcionalidades, seria mais sensato  modificar os templates da <em>aplicação</em>, e não os do <em>projeto</em>. Dessa forma, você poderia incluir a aplicação de enquete em qualquer novo projeto e ter a certeza que iria encontrar os templates personalizados que você precisa.</p>\n<p>Veja a <a class=\"reference internal\" href=\"/pt-br/6.1/ref/templates/api/#template-loaders\"><span class=\"std std-ref\">documentação de carga de template</span></a> - para mais informação sobre como o Django acha seus templates.</p>\n</section>\n</section>\n<section id=\"customize-the-admin-index-page\">\n<h2>Personalize a página inicial do site de administração<a class=\"heading-anchor\" href=\"#customize-the-admin-index-page\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>De maneira similar, você pode querer personalizar a aparência da página inicial do site de administração do Django.</p>\n<p>Por padrão, ele exibe todas as aplicações em <a class=\"reference internal\" href=\"/pt-br/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a>, que estão registrados na aplicação de administração, em ordem alfabética. E você pode querer fazer alterações significativas no layout. Além do que, a página inicial é provavelmente a página mais importante da página de administração, e deve ser fácil de usar.</p>\n<p>The template to customize is <code class=\"docutils literal notranslate\">admin/index.html</code>. (Do the same as with\n<code class=\"docutils literal notranslate\">admin/base_site.html</code> in the previous section – copy it from the default\ndirectory to your custom template directory). Edit the file, and you’ll see it\nuses a template variable called <code class=\"docutils literal notranslate\">app_list</code>. That variable contains every\ninstalled Django app. Instead of using that, you can hardcode links to\nobject-specific admin pages in whatever way you think is best.</p>\n<p>When you’re comfortable with the admin, read <a class=\"reference internal\" href=\"/pt-br/6.1/intro/tutorial08/\"><span class=\"doc\">part 8 of this\ntutorial</span></a> to learn how to use third-party packages.</p>\n</section>","rootId":"writing-your-first-django-app-part-7","toc":[{"title":"Personalize o formulário do site de administração","anchor":"customize-the-admin-form","children":[]},{"title":"Adicionando objetos relacionados","anchor":"adding-related-objects","children":[]},{"title":"Personalize a listagem da página de administração","anchor":"customize-the-admin-change-list","children":[]},{"title":"Personalize a aparência do site de administração","anchor":"customize-the-admin-look-and-feel","children":[{"title":"Personalize os templates do seu projeto","anchor":"customizing-your-project-s-templates","children":[]},{"title":"Personalize os templates da sua aplicação","anchor":"customizing-your-application-s-templates","children":[]}]},{"title":"Personalize a página inicial do site de administração","anchor":"customize-the-admin-index-page","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"Introdução","url":"/pt-br/6.1/intro/"}],"prev":{"docname":"intro/tutorial06","title":"Escrevendo sua primeira aplicação Django, parte 6","url":"/pt-br/6.1/intro/tutorial06/"},"next":{"docname":"intro/tutorial08","title":"Escrevendo seu primeiro app Django, parte 8","url":"/pt-br/6.1/intro/tutorial08/"},"formats":{"html":"/pt-br/6.1/intro/tutorial07/","markdown":"/pt-br/6.1/intro/tutorial07.md","json":"/pt-br/6.1/intro/tutorial07.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/intro/tutorial07.txt","official":"https://docs.djangoproject.com/pt-br/6.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","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}