aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/learn/server-side/django
diff options
context:
space:
mode:
Diffstat (limited to 'files/pt-br/learn/server-side/django')
-rw-r--r--files/pt-br/learn/server-side/django/admin_site/index.html364
-rw-r--r--files/pt-br/learn/server-side/django/ambiente_de_desenvolvimento/index.html431
-rw-r--r--files/pt-br/learn/server-side/django/authentication/index.html692
-rw-r--r--files/pt-br/learn/server-side/django/forms/index.html679
-rw-r--r--files/pt-br/learn/server-side/django/generic_views/index.html617
-rw-r--r--files/pt-br/learn/server-side/django/home_page/index.html420
-rw-r--r--files/pt-br/learn/server-side/django/hospedagem/index.html692
-rw-r--r--files/pt-br/learn/server-side/django/index.html75
-rw-r--r--files/pt-br/learn/server-side/django/introdução/index.html346
-rw-r--r--files/pt-br/learn/server-side/django/models/index.html459
-rw-r--r--files/pt-br/learn/server-side/django/sessões/index.html205
-rw-r--r--files/pt-br/learn/server-side/django/skeleton_website/index.html393
-rw-r--r--files/pt-br/learn/server-side/django/testing/index.html944
-rw-r--r--files/pt-br/learn/server-side/django/tutorial_website_biblioteca_local/index.html98
-rw-r--r--files/pt-br/learn/server-side/django/web_application_security/index.html187
15 files changed, 6602 insertions, 0 deletions
diff --git a/files/pt-br/learn/server-side/django/admin_site/index.html b/files/pt-br/learn/server-side/django/admin_site/index.html
new file mode 100644
index 0000000000..28b83e9d78
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/admin_site/index.html
@@ -0,0 +1,364 @@
+---
+title: 'Tutorial Django Parte 4: Django admin site'
+slug: Learn/Server-side/Django/Admin_site
+tags:
+ - Aprender
+ - Artigo
+ - Iniciante
+ - Python
+ - Tutorial
+ - django
+ - django_admin
+ - lado servidor (server-side)
+translation_of: Learn/Server-side/Django/Admin_site
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Agora que criamos modelos para o site da <a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Tutorial_website_biblioteca_local">LocalLibrary</a>, usaremos o site do Django Admin para adicionar alguns dados de livros "reais". Primeiro, mostraremos como registrar os modelos no site de administração, depois mostraremos como fazer login e criar alguns dados. No final do artigo, mostraremos algumas maneiras de melhorar ainda mais a apresentação do site Admin.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Primeiro complete: <a href="/en-US/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Usando modelos</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Para entender os benefícios e limitações do site de administração do Django, use-o para criar alguns registros para nossos modelos.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Geral">Visão Geral</h2>
+
+<p>O aplicativo de administração do Django pode usar seus modelos para criar automaticamente uma área de site que você possa usar para criar, visualizar, atualizar e excluir registros. Isso pode poupar muito tempo durante o desenvolvimento, tornando muito fácil testar seus modelos e ter uma ideia de se você tem os dados corretos. O aplicativo administrativo também pode ser útil para gerenciar dados em produção, dependendo do tipo de site. O projeto Django o recomenda apenas para gerenciamento interno de dados (ou seja, apenas para uso por administradores ou pessoas internas à sua organização), pois a abordagem centrada no modelo não é necessariamente a melhor interface possível para todos os usuários e expõe muitos detalhes desnecessários sobre os modelos.</p>
+
+<p>Toda a configuração necessária para incluir o aplicativo admin em seu site foi feita automaticamente quando você criou o <a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/skeleton_website">esqueleto do projeto</a> (para obter informações sobre as dependências reais necessárias, consulte a <a href="https://docs.djangoproject.com/pt-br/2.1/ref/contrib/admin/">documentação do Django aqui</a>). Como resultado, tudo o que você precisa fazer para adicionar seus modelos ao aplicativo administrativo é registrá-los. No final deste artigo, forneceremos uma breve demonstração de como você pode configurar ainda mais a área de administração para exibir melhor nossos dados de modelo.</p>
+
+<p>Depois de registrar os modelos, mostraremos como criar um novo "superusuário", acessar o site e criar alguns livros, autores, instâncias de livros e gêneros. Isso será útil para testar as visualizações e os modelos que começaremos a criar no próximo tutorial.</p>
+
+<h2 id="Registrando_modelos">Registrando modelos</h2>
+
+<p>Primeiro, abra o admin.py no aplicativo de catálogo (/locallibrary/catalog/admin.py). Atualmente parece com isso - note que ele já importa <code>django.contrib.admin</code>:</p>
+
+<pre class="brush: python notranslate">from django.contrib import admin
+
+# Register your models here.
+</pre>
+
+<p>Registre os modelos copiando o seguinte texto na parte inferior do arquivo. Este código simplesmente importa os modelos e, em seguida, chama <code>admin.site.register</code> para registrar cada um deles.</p>
+
+<pre class="brush: python notranslate">from catalog.models import Author, Genre, Book, BookInstance
+
+admin.site.register(Book)
+admin.site.register(Author)
+admin.site.register(Genre)
+admin.site.register(BookInstance)
+</pre>
+
+<div class="note">Nota: Se você aceitou o desafio de criar um modelo para representar a linguagem natural de um livro (<a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Models">consulte o artigo do tutorial de modelos</a>), importe-o e registre-o também!</div>
+
+<p>Essa é a maneira mais simples de registrar um modelo ou modelos no site. O site de administração é altamente personalizável e falaremos mais sobre as outras maneiras de registrar seus modelos mais abaixo.</p>
+
+<h2 id="Criando_um_super_usuário">Criando um super usuário</h2>
+
+<p>Para fazer login no site de administração, precisamos de uma conta de usuário com o status da equipe ativado. Para visualizar e criar registros, também precisamos que esse usuário tenha permissões para gerenciar todos os nossos objetos. Você pode criar uma conta "superusuário" que tenha acesso total ao site e todas as permissões necessárias usando <strong>manage.py</strong>.</p>
+
+<p>Chame o seguinte comando, no mesmo diretório que manage.py, para criar o superusuário. Você será solicitado a digitar um nome de usuário, endereço de e-mail e senha forte.</p>
+
+<pre class="brush: bash notranslate">python3 manage.py createsuperuser
+</pre>
+
+<p>Quando esse comando for concluído, um novo superusuário será adicionado ao banco de dados. Agora reinicie o servidor de desenvolvimento para que possamos testar o login:</p>
+
+<pre class="brush: bash notranslate">python3 manage.py runserver
+
+</pre>
+
+<h2 id="Fazendo_o_login_e_usando_o_site">Fazendo o login e usando o site</h2>
+
+<p>Para fazer login no site, abra o URL /<em>admin</em> (e.g. <a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin</a>) e insira suas novas credenciais de usuário e senha de superusuário (você será redirecionado para a página de login e, em seguida, de volta para o URL /<em>admin </em>depois de inserir seus detalhes).</p>
+
+<p>Esta parte do site exibe todos os nossos modelos, agrupados por aplicativo instalado. Você pode clicar no nome de um modelo para ir a uma tela que lista todos os seus registros associados e clicar nos registros para editá-los. Você também pode clicar diretamente no link Adicionar ao lado de cada modelo para começar a criar um registro desse tipo.</p>
+
+<p><img alt="Admin Site - Home page" src="https://mdn.mozillademos.org/files/13975/admin_home.png" style="display: block; height: 634px; margin: 0px auto; width: 998px;"></p>
+
+<p>Clique no link Adicionar à direita de Books para criar um novo livro (isso exibirá um diálogo muito parecido com o abaixo). Observe como os títulos de cada campo, o tipo de widget usado e o <code>help_text</code> (se houver) correspondem aos valores especificados no modelo.</p>
+
+<p>Digite valores para os campos. Você pode criar novos autores ou gêneros pressionando o botão + ao lado dos respectivos campos (ou selecione os valores existentes nas listas, se você já os criou). Quando estiver pronto, você pode pressionar<strong> SALVAR, Salvar</strong> <strong>e adicionar </strong>outro ou S<strong>alvar e continuar editando</strong> para salvar o registro.</p>
+
+<p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; height: 780px; margin: 0px auto; width: 841px;"></p>
+
+<div class="note">
+<p>Observação: neste ponto, gostaríamos que você passasse algum tempo adicionando alguns livros, autores e gêneros (por exemplo, Fantasia) à sua inscrição. Certifique-se de que cada autor e gênero inclua alguns livros diferentes (isso tornará suas visualizações de lista e detalhes mais interessantes quando forem implementadas posteriormente na série de artigos).</p>
+</div>
+
+<p>Quando terminar de adicionar livros, clique no link <strong>Home</strong> no marcador superior para ser levado de volta à página principal do administrador. Então clique no link <strong>Books </strong> para exibir a lista atual de livros (ou em um dos outros links para ver outras listas de modelos). Agora que você adicionou alguns livros, a lista pode ser semelhante à captura de tela abaixo. O título de cada livro é exibido; este é o valor retornado no modelo do livro pelo método <code>__str__()</code> que especificamos no último artigo.</p>
+
+<p><img alt="Admin Site - List of book objects" src="https://mdn.mozillademos.org/files/13935/admin_book_list.png" style="border-style: solid; border-width: 1px; display: block; height: 407px; margin: 0px auto; width: 1000px;"></p>
+
+<p>Nessa lista, você pode excluir livros marcando a caixa de seleção ao lado do livro que não deseja, selecionando a ação excluir ... na lista suspensa Ação e pressionando o botão Ir. Você também pode adicionar novos livros pressionando o botão <strong>ADD BOOK</strong>. </p>
+
+<p>Você pode editar um livro selecionando seu nome no link. A página de edição de um livro, mostrada abaixo, é quase idêntica à página "Adicionar". As principais diferenças são o título da página (Change book) e a adição de botões <strong>Delete</strong>, <strong>HISTORY</strong> e <strong>VIEW ON SITE</strong> (este último botão aparece porque definimos o método <code>get_absolute_url()</code> em nosso modelo).</p>
+
+<p><img alt="Admin Site - Book Edit" src="https://mdn.mozillademos.org/files/13977/admin_book_modify.png" style="border-style: solid; border-width: 1px; display: block; height: 780px; margin: 0px auto; width: 841px;"></p>
+
+<p>Agora navegue de volta para o <strong>Home</strong> page (usando o link Home, a trilha de navegação) e, em seguida, <strong>Author</strong> e listas de <strong>Genre</strong> — você já deve ter criado a partir de quando adicionou os novos livros, mas fique à vontade para adicionar um pouco mais.</p>
+
+<p>O que você não terá é qualquer instância do livro, porque elas não são criadas a partir de livros (embora você possa criar <code>Book</code> a partir de <code>BookInstance</code> — esta é a natureza da <code>ForeignKey</code> field). Navegue de volta para a<em> Página inicial</em> e pressione o botão <em>Adicionar</em> associado para exibir a tela <em>Adicionar instância</em> do livro abaixo. Observe o ID grande e globalmente exclusivo, que pode ser usado para identificar separadamente uma única cópia de um livro na biblioteca.</p>
+
+<p><img alt="Admin Site - BookInstance Add" src="https://mdn.mozillademos.org/files/13981/admin_bookinstance_add.png" style="border-style: solid; border-width: 1px; display: block; height: 514px; margin: 0px auto; width: 863px;"></p>
+
+<p>Crie vários desses registros para cada um de seus livros. Defina o status como <em>Disponível</em> para pelo menos alguns registros e <em>Em empréstimo</em> para outros. Se o status <strong>não </strong>for <em>Disponível</em>, defina também uma <em>data de vencimento</em> futura.</p>
+
+<p>É isso aí! Agora você aprendeu como configurar e usar o site de administração. Você também criou registros para <code>Book</code>, <code>BookInstance</code>, <code>Genre</code>, e <code>Author</code> que poderemos usar assim que criarmos nossas próprias visualizações e modelos.</p>
+
+<h2 id="Configuração_Avançada">Configuração Avançada</h2>
+
+<p>O Django faz um bom trabalho ao criar um site de administração básico usando as informações dos modelos registrados:</p>
+
+<ul>
+ <li>Cada modelo possui uma lista de registros individuais, identificados pela string criada com o método <code>__str__()</code> do modelo, e vinculado a visualizações de views/forms para edição. Por padrão, essa exibição tem um menu de ação na parte superior que você pode usar para executar operações de exclusão em massa nos registros.</li>
+ <li>Os formulários de registro de detalhes do modelo para edição e adição de registros contêm todos os campos do modelo, dispostos verticalmente em sua ordem de declaração.  </li>
+</ul>
+
+<p>Você pode personalizar ainda mais a interface para torná-la ainda mais fácil de usar. Algumas das coisas que você pode fazer são:</p>
+
+<ul>
+ <li>List views:
+ <ul>
+ <li>Adicionar adicional fields/information exibido para cada registro.</li>
+ <li>Adicione filtros para selecionar quais registros são listados, com base na data ou em algum outro valor de seleção (e.g. Book loan status).</li>
+ <li>Adicione opções adicionais ao menu de ações nas exibições de lista e escolha onde esse menu é exibido no formulário.</li>
+ </ul>
+ </li>
+ <li>Detail views
+ <ul>
+ <li>Escolha quais campos exibir (ou excluir), junto com sua ordem, agrupamento, se eles são editáveis, o widget usado, a orientação etc.</li>
+ <li>Adicione campos relacionados a um registro para permitir a edição imediata (por exemplo, adicione a capacidade de adicionar e editar registros de livros enquanto cria o registro de autor).</li>
+ </ul>
+ </li>
+</ul>
+
+<p>In this section we're going to look at a few changes that will improve the interface for our <em>LocalLibrary</em>, including adding more information to <code>Book</code> and <code>Author</code> model lists, and improving the layout of their edit views. We won't change the <code>Language</code> and <code>Genre</code> model presentation because they only have one field each, so there is no real benefit in doing so!</p>
+
+<p>You can find a complete reference of all the admin site customisation choices in <a href="https://docs.djangoproject.com/en/2.0/ref/contrib/admin/">The Django Admin site</a> (Django Docs).</p>
+
+<h3 id="Registrando_uma_classe_ModelAdmin">Registrando uma classe ModelAdmin</h3>
+
+<p>Para alterar como um modelo é exibido na interface de administração, você define uma classe ModelAdmin (que descreve o layout) e registra-o no modelo.</p>
+
+<p>Vamos começar com o <code>Author</code> model. Abra <strong>admin.py</strong> no aplicativo de catálogo (/locallibrary/catalog/admin.py). Comente o seu registro original (prefixo com um #) para o <code>Author</code> model:</p>
+
+<pre class="brush: js notranslate"># admin.site.register(Author)</pre>
+
+<p>Agora adicione um novo <code>AuthorAdmin</code> e registre como mostrado abaixo.</p>
+
+<pre class="brush: python notranslate"># Define the admin class
+class AuthorAdmin(admin.ModelAdmin):
+ pass
+
+# Register the admin class with the associated model
+admin.site.register(Author, AuthorAdmin)
+</pre>
+
+<p>Agora vamos adicionar as classes <code>ModelAdmin</code> para <code>Book</code>, e <code>BookInstance</code>. Precisamos novamente comentar os registros originais:</p>
+
+<pre class="brush: js notranslate"># admin.site.register(Book)
+# admin.site.register(BookInstance)</pre>
+
+<p>Agora, para criar e registrar os novos modelos; para o propósito desta demonstração, vamos usar o <code>@register</code> decorador para registrar os modelos (isso faz exatamente a mesma coisa que <code>admin.site.register()</code> sintaxe):</p>
+
+<pre class="brush: python notranslate"># Register the Admin classes for Book using the decorator
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+ pass
+
+# Register the Admin classes for BookInstance using the decorator
+@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+ pass
+</pre>
+
+<p>Atualmente todas as nossas classes administrativas estão vazias (veja <code>pass</code>) então o comportamento do administrador não será alterado! Agora podemos estendê-los para definir nosso comportamento administrativo específico do modelo.</p>
+
+<h3 id="Configure_list_views">Configure list views</h3>
+
+<p>A LocalLibrary atualmente lista todos os autores usando o nome do objeto gerado a partir do método <code>__str__()</code> do modelo. Isso é bom quando você tem apenas alguns autores, mas quando você tem muitos, você pode acabar tendo duplicatas. Para diferenciá-los, ou apenas porque você quer mostrar informações mais interessantes sobre cada autor, você pode usar <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display">list_display</a> para adicionar campos adicionais à vista.</p>
+
+<p>Substitua seu<code>AuthorAdmin</code> class com o código abaixo. Os nomes de campo a serem exibidos na lista são declarados em uma <em>tupla </em>na ordem requerida, conforme mostrado (esses são os mesmos nomes especificados em seu modelo original).</p>
+
+<pre class="brush: python notranslate">class AuthorAdmin(admin.ModelAdmin):
+ list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+</pre>
+
+<p>Agora navegue até a lista de autores em seu site. Os campos acima devem agora ser exibidos, assim:</p>
+
+<p><img alt="Admin Site - Improved Author List" src="https://mdn.mozillademos.org/files/14023/admin_improved_author_list.png" style="border-style: solid; border-width: 1px; display: block; height: 302px; margin: 0px auto; width: 941px;"></p>
+
+<p>Para o nosso <code>Book</code> model nós vamos adicionalmente exibir o <code>author</code> e <code>genre</code>. O <code>author</code> é uma variável <code>ForeignKey</code> (um-para-um) relacionamento, e assim será representado pelo valor <code>__str__()</code> para o registro associado. Substitua o <code>BookAdmin</code> class com a versão abaixo.</p>
+
+<pre class="brush: python notranslate">class BookAdmin(admin.ModelAdmin):
+ list_display = ('title', 'author', 'display_genre')
+</pre>
+
+<p>Infelizmente não podemos especificar diretamente a variável  <font face="Consolas, Liberation Mono, Courier, monospace">genre </font>na <code>list_display</code> porque é um <code>ManyToManyField</code>(O Django evita isso porque há um grande "custo" de acesso ao banco de dados ao fazer isso). Em vez disso, vamos definir uma função <code>display_genre</code> para obter as informações como uma string (esta é a função que chamamos acima; vamos defini-lo abaixo).</p>
+
+<div class="note">
+<p>Nota: Obtendo o <code>genre</code> pode não ser uma boa ideia aqui, por causa do "custo" da operação do banco de dados. Estamos mostrando como as funções de chamada em seus modelos podem ser muito úteis por outros motivos - por exemplo, para adicionar um link <em>Apagar </em>ao lado de cada item da lista.</p>
+</div>
+
+<p>Adicione o seguinte código ao seu <code>Book</code> model (<strong>models.py</strong>). Isso cria uma string a partir dos três primeiros valores da variavel <code>genre</code> (se existirem) e cria um <code>short_description</code> que pode ser usado no site administrativo para esse método.</p>
+
+<pre class="brush: python notranslate">    def display_genre(self):
+ """Create a string for the Genre. This is required to display genre in Admin."""
+ return ', '.join(genre.name for genre in self.genre.all()[:3])
+
+ display_genre.short_description = 'Genre'
+</pre>
+
+<p>Depois de salvar o modelo e o administrador atualizado, abra o site e vá para a página da lista Livros; você deve ver uma lista de livros como a abaixo:</p>
+
+<p><img alt="Admin Site - Improved Book List" src="https://mdn.mozillademos.org/files/14025/admin_improved_book_list.png" style="border-style: solid; border-width: 1px; display: block; height: 337px; margin: 0px auto; width: 947px;"></p>
+
+<p>O <code>Genre</code> model (e a <code>Language</code> model, se você definiu um) ambos têm um único campo, portanto, não faz sentido criar um modelo adicional para exibir campos adicionais.</p>
+
+<div class="note">
+<p>Nota: Vale a pena atualizar o<code>BookInstance</code> model list para mostrar pelo menos o status e a data de retorno esperada. Nós adicionamos isso como um desafio no final deste artigo!</p>
+</div>
+
+<h3 id="Adicionando_list_filters">Adicionando list filters</h3>
+
+<p>Uma vez que você tenha muitos itens em uma lista, pode ser útil filtrar quais itens são exibidos. Isso é feito listando os campos no atributo <code>list_filter</code>. Substitua sua atual <code style="font-style: normal; font-weight: normal;">BookInstanceAdmin</code> class com o fragmento de código abaixo.</p>
+
+<pre class="brush: python notranslate">class BookInstanceAdmin(admin.ModelAdmin):
+<strong> list_filter = ('status', 'due_back')</strong>
+</pre>
+
+<p>A visualização de lista agora incluirá uma caixa de filtro à direita. Observe como você pode escolher datas e status para filtrar os valores:</p>
+
+<p><img alt="Admin Site - BookInstance List Filters" src="https://mdn.mozillademos.org/files/14037/admin_improved_bookinstance_list_filters.png" style="height: 528px; width: 960px;"></p>
+
+<h3 id="Organizando_o_layout_da_detail_view">Organizando o layout da detail view</h3>
+
+<p>Por padrão, as exibições detalhadas exibem todos os campos verticalmente, em sua ordem de declaração no modelo. Você pode alterar a ordem da declaração, quais campos são exibidos (ou excluídos), se as seções são usadas para organizar as informações, se os campos são exibidos horizontalmente ou verticalmente e até mesmo quais widgets de edição são usados nos formulários admin.</p>
+
+<div class="note">
+<p>Nota: Os modelos <em>LocalLibrary </em>são relativamente simples, portanto não é necessário alterar o layout; No entanto, faremos algumas alterações, só para mostrar como.</p>
+</div>
+
+<h4 id="Controlando_quais_campos_são_exibidos">Controlando quais campos são exibidos</h4>
+
+<p>Atualize seu <code>AuthorAdmin</code> class para adicionar a linha <code>fields</code>, como mostrado abaixo (em negrito):</p>
+
+<pre class="brush: python notranslate">class AuthorAdmin(admin.ModelAdmin):
+ list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+<strong> fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]</strong>
+</pre>
+
+<p>O atributo <code>fields</code> lista apenas os campos que devem ser exibidos no formulário, em ordem. Os campos são exibidos verticalmente por padrão, mas serão exibidos horizontalmente se você agrupá-los posteriormente em uma tupla (conforme mostrado nos campos "data" acima).</p>
+
+<p>No seu site, acesse a visualização de detalhes do autor. Agora, ele deve aparecer como mostrado abaixo:</p>
+
+<p><img alt="Admin Site - Improved Author Detail" src="https://mdn.mozillademos.org/files/14027/admin_improved_author_detail.png" style="border-style: solid; border-width: 1px; display: block; height: 282px; margin: 0px auto; width: 928px;"></p>
+
+<div class="note">
+<p>Nota: você também pode usar o atributo <code>exclude</code> para declarar uma lista de atributos a serem excluídos do formulário (todos os outros atributos no modelo serão exibidos).</p>
+</div>
+
+<h4 id="Seccionando_a_detail_view">Seccionando a detail view</h4>
+
+<p>Você pode adicionar "seções" para agrupar informações de modelo relacionadas dentro do formulário detalhado, usando o atributo <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets">fieldsets</a>.</p>
+
+<p>Na <code>BookInstance</code> model temos informações relacionadas ao que o livro é (i.e. <code>name</code>, <code>imprint</code>, e <code>id</code>) e quando estará disponível (<code>status</code>, <code>due_back</code>). Podemos adicionar estes em diferentes seções, adicionando o texto em negrito para o nosso <code>BookInstanceAdmin</code> class. </p>
+
+<pre class="brush: python notranslate">@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+ list_filter = ('status', 'due_back')
+
+<strong> fieldsets = (
+ (None, {
+ 'fields': ('book', 'imprint', 'id')
+ }),
+ ('Availability', {
+ 'fields': ('status', 'due_back')
+ }),
+ )</strong></pre>
+
+<p>Cada seção tem seu próprio título (ou <code>None</code>,se você não quiser um título) e uma tupla associada de campos em um dicionário - o formato é complicado de descrever, mas bastante fácil de entender se você olhar o fragmento de código imediatamente acima.</p>
+
+<p>Agora, navegue até uma visualização de instância do livro em seu website; o formulário deve aparecer como mostrado abaixo:</p>
+
+<p><img alt="Admin Site - Improved BookInstance Detail with sections" src="https://mdn.mozillademos.org/files/14029/admin_improved_bookinstance_detail_sections.png" style="border-style: solid; border-width: 1px; display: block; height: 580px; margin: 0px auto; width: 947px;"></p>
+
+<h3 id="Edição_inline_de_registros_associados">Edição inline de registros associados</h3>
+
+<p>Às vezes, pode fazer sentido adicionar registros associados ao mesmo tempo. Por exemplo, pode fazer sentido ter as informações do livro e as informações sobre as cópias específicas que você tem na mesma página de detalhes.</p>
+
+<p>Você pode fazer isso declarando <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.inlines">inlines</a>, do tipo <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.TabularInline">TabularInline</a> (horizonal layout) or <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.StackedInline">StackedInline</a> (layout vertical, assim como o layout do modelo padrão). Você pode adicionar ao <code>BookInstance</code> informações inline para o nosso <code>Book</code> detalhe, adicionando as linhas abaixo em negrito perto do seu <code>BookAdmin</code>:</p>
+
+<pre class="brush: python notranslate"><strong>class BooksInstanceInline(admin.TabularInline):
+    model = BookInstance</strong>
+
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+    list_display = ('title', 'author', 'display_genre')
+<strong>    inlines = [BooksInstanceInline]</strong>
+</pre>
+
+<p>Agora navegue até uma view pala um <code>Book</code> no seu site - na parte inferior, você verá as instâncias do livro relacionadas a este livro (imediatamente abaixo dos campos de gênero do livro):</p>
+
+<p><img alt="Admin Site - Book with Inlines" src="https://mdn.mozillademos.org/files/14033/admin_improved_book_detail_inlines.png" style="border-style: solid; border-width: 1px; display: block; height: 889px; margin: 0px auto; width: 937px;"></p>
+
+<p>Nesse caso, tudo o que fizemos foi declarar nossa classe inline tabular, que apenas adiciona todos os campos do modelo embutido. Você pode especificar todos os tipos de informações adicionais para o layout, incluindo os campos a serem exibidos, sua ordem, se eles são somente leitura ou não, etc. (veja <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.TabularInline">TabularInline</a> para maiores informações).</p>
+
+<div class="note">
+<p>Nota: Existem alguns limites dolorosos nesta funcionalidade! Na captura de tela acima, temos três instâncias de livros existentes, seguidas de três espaços reservados para novas instâncias de livros (que são muito semelhantes!). Seria melhor não ter instâncias do livro reserva por padrão e apenas adicioná-las com o link <strong>Add another Book instance</strong> , ou poder listar apenas <code>BookInstance</code>s como links não legíveis daqui. A primeira opção pode ser feita configurando atributo <code>extra</code> para 0 no <code>BooksInstanceInline</code> model, tente você mesmo.</p>
+</div>
+
+<h2 id="Desafie-se">Desafie-se</h2>
+
+<p>Aprendemos muito nesta seção, então agora é hora de você tentar algumas coisas.</p>
+
+<ol>
+ <li>Para a <em>listview</em> <code>BookInstance</code>, adicione o código para exibir o livro, o status, a data de devolução e o id (em vez do texto padrão <code>__str__()</code>).</li>
+ <li>Adicione uma listagem <em>inline</em> de itens <code>Book</code> para a lista detalhada de <code>Author</code> usando a mesma abordagem que fizemos para  <code>Book</code>/<code>BookInstance</code>.</li>
+</ol>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>É isso aí! Agora você aprendeu como configurar o site de administração na sua forma simples e aprimorada, como criar um superusuário, como navegar no site de administração e visualizar, excluir e atualizar registros. Ao longo do caminho você criou um monte de Livros, Instâncias de livros, Gêneros e Autores que poderemos listar e exibir assim que criarmos nossas próprias <em>views</em> e <em>templates</em>.</p>
+
+<h2 id="Leitura_adicional">Leitura adicional</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.0/intro/tutorial02/#introducing-the-django-admin">Escrevendo seu primeiro app Django, parte 2: Apresentando o Django Admin</a>  (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.0/ref/contrib/admin/">O Django Admin site</a> (Django Docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma biblioteca local</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando o escopo do website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Parte 3: Utilizando models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Parte 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Segurança de aplicações Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/ambiente_de_desenvolvimento/index.html b/files/pt-br/learn/server-side/django/ambiente_de_desenvolvimento/index.html
new file mode 100644
index 0000000000..101d1a15ad
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/ambiente_de_desenvolvimento/index.html
@@ -0,0 +1,431 @@
+---
+title: Configurando um ambiente de desenvolvimento Django
+slug: Learn/Server-side/Django/ambiente_de_desenvolvimento
+tags:
+ - Ambiente de desenvolvimento
+ - Aprender
+ - Iniciante
+ - Instalação
+ - Introdução
+ - Python
+ - django
+translation_of: Learn/Server-side/Django/development_environment
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}</div>
+
+<p>Agora que você sabe para que serve o Django, nós iremos te mostrar como instalar, configurar e testar um ambiente de desenvolvimento no Windows, Linux (Ubuntu), e macOS - seja qual for o sistema operacional (SO) que você usar, este artigo deve fornecê-lo o suficiente para conseguir começar a desenvolver aplicativos Django.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Saber como usar um teminal / linha de comando. Saber instalar softwares em seu sistema operacional.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Ter uma ambiente de desenvolvimento Django (2.0) operando em seu computador.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_geral_do_ambiente_de_desenvolvimento_Django">Visão geral do ambiente de desenvolvimento Django</h2>
+
+<p>Django facilita muito a configuração em seu computador para iniciar logo o desenvolvimento de aplicações web. Essa seção explica o que você ganha com o ambiente de desenvolvimento e fornece um plano geral de algumas opções de instalação e configuração. O resto do artigo explica o método <em>recomendado</em> de instalar o ambiente Django no Ubuntu, macOS e Windows e como testar.</p>
+
+<h3 id="O_que_é_o_ambiente_de_desenvolvimento_Django">O que é o ambiente de desenvolvimento Django?</h3>
+
+<p>O ambiente de desenvolvimento é uma instalação do Django em seu computador local para que você use-o para desenvolver e testar apps Django antes de implementá-los em um ambiente de produção</p>
+
+<p>A principal ferramenta que Django fornece é um conjunto de scripts Python para criar e trabalhar com projetos Django, junto com um simples<em> webserver de desenvolvimento</em> que você pode usar para testar localmente (i.e. no seu computador, não em um web server externo) aplicações web Django no seu navegador.</p>
+
+<p>Existem outras ferramentas secundárias que fazem parte do ambiente de desenvolvimento que não cobriremos aqui. Isso inclui coisas como um <a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Available_text_editors">editor de texto</a> ou IDE para edição de código, e uma ferramenta pra gerenciamento do controle de origem de códigos (como o <a href="https://git-scm.com/">Git</a>) para administrar com segurança as diferentes versões de seu sistema. Nós estamos assumindo que você já tem um editor de texto instalado.</p>
+
+<h3 id="Quais_são_as_opções_de_instalação_do_Django">Quais são as opções de instalação do Django?</h3>
+
+<p>Django é extremamente flexível em termos de como e onde ele pode ser instalado e configurado. Django pode:</p>
+
+<ul>
+ <li>Ser instalado em diferentes sistemas operacionais.</li>
+ <li>Ser instalado pelo código-fonte, pelo Python Package Index (PyPi) e, em muitos casos, pelo aplicativo gerenciador de pacotes do computador host.</li>
+ <li>Ser configurado para uso de um dos vários bancos de dados, que também podem ser instalados e configurados separadamente.</li>
+ <li>Operar no ambiente principal do sistema Python ou em ambientes virtuais Python, separadamente.</li>
+</ul>
+
+<p>Cada opção requer leves diferenças de configuração e instalação. As subseções abaixo explicam algumas de suas escolhas. No resto do artigo nós iremos mostrar como instalar o Django em um pequeno número de sistemas operacionais. No resto do módulo, assumiremos que você tenha instalado o Django em sua máquina.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Outras possíveis opções de instalação são cobertas pela documentação oficial do Django. Nós linkamos os <a href="#Veja_também" id="See_also">documents adequados abaixo</a>.</p>
+</div>
+
+<h4 id="Quais_sistemas_operacionais_suportam_Django">Quais sistemas operacionais suportam Django?</h4>
+
+<p>Aplicações web Django podem rodar em quase todas as maquinas que suportam a linguagem de programação Python 3. Windows, macOS, Linux/Unix e Solaris são alguns desses SO's. A maioria dos computadores atuais devem ter o desempenho necessário para operar Django.</p>
+
+<p>Neste artigo, iremos fornecer instruções para Windows, macOS a Linux/Unix.</p>
+
+<h4 id="Qual_versão_de_Python_deve_ser_usada">Qual versão de Python deve ser usada?</h4>
+
+<p>Nós recomendamos que use a mais recente versão disponível — no momento que escrevo é Python 3.7.1.</p>
+
+<p>Se necessário, versões a partir de Python 3.5 podem ser usadas (o suporte para Python 3.5 irá acabar em versões futuras).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Python 2.7 não pode ser usado com Django 2.1 (A série Django 1.11.x é a última  que suporta Python 2.7).</p>
+</div>
+
+<h4 id="Onde_posso_baixar_o_Django">Onde posso baixar o Django?</h4>
+
+<p>Existem três lugares para fazer o download do Django:</p>
+
+<ul>
+ <li>Python Package Repository (PyPi), usando o comando <em>pip</em>. Esta é a melhor forma de conseguir a última versão estável do Django.</li>
+ <li>A partir de uma versão do gerenciador de pacotes de seu computador. Distribuições de Django que são empacotadas com o sistema operacional oferecem uma "instalação familiar". Contudo, note que a versão disponível pode ser um pouco antiga, e que pode ser instalada apenas dentro do sistema ambiente do Python (podendo ser algo que você não queira).</li>
+ <li>Instalar pelo código-fonte. Você pode pegar a última versão acessível do código do Django e instalar no seu computador. Não é recomendado aos iniciantes, mas é necessário quando você se sentir pronto para contribuir com o Django.</li>
+</ul>
+
+<p>Este artigo mostra a instalação pelo Pypi, pois queremos a última versão estável do Django.</p>
+
+<h4 id="Qual_banco_de_dados">Qual banco de dados?</h4>
+
+<p>Django suporta (principalmente) quatro bancos de dados (PostgreSQL, MySQL, Oracle, e SQLite ), contudo, existem bibliotecas community que fornecem níveis variados de suporte para outros populares bancos de dados SQL e NoSQL. Nós recomendamos que você use o mesmo banco de dados tanto para produção quanto para desenvolvimento (embora o Django abstraia muitas das diferenças dos bancos de dados usando seu Object-Relational Mapper (ORM), ainda há <a href="https://docs.djangoproject.com/en/2.1/ref/databases/">problemas em potencial</a> que é melhor evitar).</p>
+
+<p>Neste artigo (e na maior parte deste módulo) nós usaremos o banco de Dados <em>SQL</em><em>ite</em>, que armazena dados em um arquivo. SQLite é destinado para uso sendo um banco de dados leve e que não consegue suportar uma demanda muito alta. Entretanto, uma excelente opção para aplicações de que focam em leitura de dados.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Django é configurado por padrão a usar SQLite ao iniciar seu projeto usando as ferramentas padrão (django-admin). É uma ótima escolha quando você está começando, porque não requer configurações adicionais ou instalações.</p>
+</div>
+
+<h4 id="Instalar_em_todo_o_sistema_ou_em_um_ambiente_virtual_Python">Instalar em todo o sistema ou em um ambiente virtual Python?</h4>
+
+<p>Quando você instala Python 3 você pega um único ambiente global que é compartilhado por todo o código Python 3. Enquanto você pode instalar qualquer pacote Python que quiser no ambiente, você pode instalar apenas uma versão particular de cada pacote por vez.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Aplicações Python instaladas no ambiente global têm forte potêncial de entrar em conflito entre si (i.e. se elas dependem de versões diferentes do mesmo pacote).</p>
+</div>
+
+<p>Se você instalar Django no ambiente padrão/global você só será capaz de ter uma versão do Django em seu computador. Isto pode ser um problema se você quer criar novos websites (usando a versão mais recente do Django) enquanto ainda realiza manutenção nos websites que dependem das versões antigas.</p>
+
+<p>Pensando nisso, desenvolvedores experientes de Python/Django normalmente executam apps Python dentro de um <em>ambiente virtual Python </em>independente. Isso permite usar diferentes ambientes Django em um único computador. A própria equipe de desenvolvedores Django recomenda o uso de ambientes virtuais Python!</p>
+
+<p>Esse módulo assume que você instalou o Django em um ambiente virtual, nós iremos mostrá-lo como fazer isso logo abaixo.</p>
+
+<h2 id="Instalando_Python_3">Instalando Python 3</h2>
+
+<p>Você deve ter Python instalado em seu sistema operacional para usar Django. Se você estiver usando <em>Python 3</em>, também precisará da ferramenta <a href="https://pypi.python.org/pypi">Python Package Index</a> — <em>pip3 </em>— que é usada para administrar (instalar, editar, remover) pacotes/bibliotecas Python usadas por Django e seus outros aplicativos Python.</p>
+
+<p>Essa parte explica brevemente como você pode checar quais versões de Python estão disponíveis e instalar novas versões se necessário (em Ubuntu 18.04, macOS e Windows 10).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Dependendo da sua plataforma, você também pode instalar Python/pip3 no seu sistema operacional através de seu próprio gerenciador de pacotes ou por outros mecanismos. Para a maioria das plataformas, você pode baixar os arquivos necessários para instalação em <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a> e instalá-los usando o método específico da plataforma em questão.</p>
+</div>
+
+<h3 id="Ubuntu_18.04">Ubuntu 18.04</h3>
+
+<p>Ubuntu Linux 18.04 LTS inclui Python 3.6.6 por padrão. Você pode confirmar isso executando o seguinte comando no Terminal:</p>
+
+<pre class="brush: bash notranslate"><span style="line-height: 1.5;">python3 -V
+ Python 3.6.6</span></pre>
+
+<p>Contudo, o Python Package Index, que você precisará para instalar pacotes para Python 3 (incluindo Django), <strong>não</strong> está disponível por padrão. Você pode instalar pip3 pelo Terminal usando:</p>
+
+<pre class="brush: bash notranslate">sudo apt install python3-pip
+</pre>
+
+<h3 id="macOS">macOS</h3>
+
+<p>macOS "El Capitan" e outras versões mais recentes não incluem Python 3. Você pode confirmar isto executando os comandos abaixo no Terminal:</p>
+
+<pre class="brush: bash notranslate"><span style="line-height: 1.5;">python3 -V
+ </span>-bash: python3: command not found</pre>
+
+<p>Você pode instalar Python 3 (com a ferramenta pip3) facilmente em <a href="https://www.python.org/">python.org</a>:</p>
+
+<ol>
+ <li>Baixe o instalador exigido:
+ <ol>
+ <li>Acesse <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></li>
+ <li>Selecione o botão <strong>Download Python 3.7.1</strong> (o número exato da versão menor pode diferir).</li>
+ </ol>
+ </li>
+ <li>Localize o arquivo usando <em>o Finder</em>, e clique duplo no arquivo do pacote. Siga os passos da instalação dos prompts.</li>
+</ol>
+
+<p>Agora você pode confirmar se tudo deu certo checando o<em> Python 3 </em>como mostrado abaixo:</p>
+
+<pre class="brush: bash notranslate"><span style="line-height: 1.5;">python3 -V
+ Python 3.7.1</span>
+</pre>
+
+<p>Você pode checar se<em> pip3</em> está instalado listando todos os pacotes disponíveis.</p>
+
+<pre class="brush: bash notranslate">pip3 list</pre>
+
+<h3 id="Windows_10">Windows 10</h3>
+
+<p>Windows não inclui Python por padrão, mas você pode instalá-lo facilmente (com a ferramenta<em> pip3</em>) em <a href="https://www.python.org/">python.org</a>:</p>
+
+<ol>
+ <li>Baixe o instalador exigido:
+ <ol>
+ <li>Acesse <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></li>
+ <li>Selecione o botão <strong>Download Python 3.7.1</strong> (o número exato da versão menor pode diferir).</li>
+ </ol>
+ </li>
+ <li>Instale Python com um clique duplo no arquivo baixado e siga a instalação dos prompts.</li>
+ <li>Tenha certeza que a caixa "Add Python to PATH" está checada.</li>
+</ol>
+
+<p>Você pode verificar se o Python 3 foi instalado colocando o seguinte texto no Prompt de Comando</p>
+
+<pre class="brush: bash notranslate"><span style="line-height: 1.5;">py -3 -V
+ Python 3.7.1</span>
+</pre>
+
+<p>O instalador do Windows incorpora<em> pip3</em> (o administrador de pacotes Python) por padrão. Você pode facilmente listar os pacotes instalados com o comando abaixo:</p>
+
+<pre class="brush: bash notranslate"><span style="line-height: 1.5;">pip3 list</span>
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: O instalador deve ter configurado tudo que você precisa antes para esse comando funcionar. Se for exibida uma mensagem que Python não encontrou, você pode ter esquecido de adicioná-lo ao PATH do Sistema. Você pode fazer isso exexutando o instalador novamente, selecionando "Modify", e checando a caixa chamada " Add Python to environment variables "  na segunda tela.</p>
+</div>
+
+<h2 id="Usando_Django_em_um_ambiente_virtual_Python">Usando Django em um ambiente virtual Python</h2>
+
+<p>As bibliotecas que nós iremos usar para criar nossos ambientes virtuais são <a href="https://virtualenvwrapper.readthedocs.io/en/latest/index.html">virtualenvwrapper</a> (Linux e macOS) e <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> (Windows), sendo que ambas usam a ferramenta <a href="https://developer.mozilla.org/en-US/docs/Python/Virtualenv">virtualenv</a>. as bibliotecas criam uma interface consistente para manusear interfaces em todas plataformas;</p>
+
+<h3 id="Instalando_o_software_de_ambiente_virtual">Instalando o software de ambiente virtual</h3>
+
+<h4 id="Instalação_do_ambiente_virtual_no_Ubuntu">Instalação do ambiente virtual no Ubuntu</h4>
+
+<p>Após instalar Python e pip, você pode instalar<em> virtualenvwrapper</em> (que inclui<em>virtualenv</em>). O guia oficial para a instalação pode ser encontrado <a href="http://virtualenvwrapper.readthedocs.io/en/latest/install.html">aqui</a>, ou siga as instruções abaixo.</p>
+
+<p>Instale a ferramenta usando<em> pip3</em>:</p>
+
+<pre class="brush: bash notranslate"><code>sudo pip3 install virtualenvwrapper</code></pre>
+
+<p>Em seguida, adicione as linhas abaixo no fim de seu arquivo shell startup (este é um arquivo oculto nomeado <strong>.bashrc </strong>em seu diretório home). Isto coloca a localização de onde seus ambientes virtuais deveriam estar, a localização dos diretórios para desevolvimento de projetos e a localização do script instalado com o pacote.</p>
+
+<pre class="brush: bash notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 '
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh</code>
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: As variáveis <code>VIRTUALENVWRAPPER_PYTHON</code> e <code>VIRTUALENVWRAPPER_VIRTUALENV_ARGS </code>apontam para  a localização em uma instalação normal de Python 3, e <code>source /usr/local/bin/virtualenvwrapper.sh</code> aponta para a localização normal do script <code>virtualenvwrapper.sh</code> Se<em> virtualenv</em> não funciona quando você testa, uma coisa a se verificar é se o Python e o script estão na localização esperada (e então alterar o arquivo de startup com os caminhos corretos).<br>
+ <br>
+ Você pode encontrar a localização correta no seu sistema usando os comandos <code>which virtualenvwrapper.sh</code> e <code>which python3</code>.</p>
+</div>
+
+<p>Recarregue o arquivo de startup executando o seguinte comando no Terminal:</p>
+
+<pre class="brush: bash notranslate"><code>source ~/.bashrc</code></pre>
+
+<p>Após executar o comando, você deveria ver scripts como esses:</p>
+
+<pre class="brush: bash notranslate"><code>virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_details</code>
+</pre>
+
+<p>Agora você pode criar um novo ambiente virtual com o comando <code>mkvirtualenv</code>.</p>
+
+<h4 id="Instalação_do_ambiente_virtual_no_macOS">Instalação do ambiente virtual no macOS</h4>
+
+<p>Instalar<em> virtualenvwrapper</em> no macOS é quase a mesma coisa que instalar no Ubuntu (novamente, você pode seguir as instruções do <a href="http://virtualenvwrapper.readthedocs.io/en/latest/install.html">guia oficial de instalação </a>ou as instruções abaixo).</p>
+
+<p>Instale<em> virtualenvwrapper</em> (e<em> virtualenv</em>) usando<em> pip</em> como abaixo.</p>
+
+<pre class="brush: bash notranslate"><code>sudo pip3 install virtualenvwrapper</code></pre>
+
+<p>Então adicione as seguintes linhas no arquivo de startup do seu shell.</p>
+
+<pre class="brush: bash notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh</code></pre>
+
+<div class="note">
+<p><strong>Note</strong>: A variável <code>VIRTUALENVWRAPPER_PYTHON</code>  aponta para uma localização em uma instalação normal de Python 3, e <code>source /usr/local/bin/virtualenvwrapper.sh</code> aponta para a localização comum do script <code>virtualenvwrapper.sh</code>. Se <em>virtualenv</em> não funciona quando você testa, uma coisa a se verificar é se o Python e o script estão na localização esperada (e então alterar o arquivo de startup com os caminhos corretos).</p>
+
+<p>Por exemplo, uma instalação teste no macOS termina com as seguintes linhas no arquivo de startup:</p>
+
+<pre class="brush: bash notranslate">export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /Library/Frameworks/Python.framework/Versions/3.7/bin/virtualenvwrapper.sh</pre>
+
+<p>Você pode encontrar a localização correta no seu sistema usando os comandos <code>which virtualenvwrapper.sh</code> e <code>which python3</code>.</p>
+</div>
+
+<p>São as mesmas linhas digitadas no Ubuntu, mas o arquivo de startup é diferente nomeado como <strong>.bash_profile</strong>, oculto no seu diretório home.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Se você não acha o arquivo <strong>.bash_profile</strong> pelo finder, você pode abir pelo terminal usando o <em>nano</em>.</p>
+
+<p>Os comandos são como esses:</p>
+
+<pre class="notranslate"><code>cd ~ # Navigate to my home directory
+ls -la #List the content of the directory. YOu should see .bash_profile
+nano .bash_profile # Open the file in the nano text editor, within the terminal
+# Scroll to the end of the file, and copy in the lines above
+# Use Ctrl+X to exit nano, Choose Y to save the file.</code>
+</pre>
+</div>
+
+<p>Atualize o arquivo de startup fazendo o seguinte chamado no terminal:</p>
+
+<pre class="brush: bash notranslate"><code>source ~/.bash_profile</code></pre>
+
+<p>Com isso, você deveria ver alguns scripts na tela do terminal sendo executados (os mesmos scripts da instalação no Ubuntu). Agora você está apto a criar um novo ambiente virtual pelo comando <code>mkvirtualenv</code>.</p>
+
+<h4 id="Instalação_do_ambiente_virtual_no_Windows_10">Instalação do ambiente virtual no Windows 10</h4>
+
+<p>Instalar <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> é ainda mais simples que instalar <em>virtualenvwrapper</em>, porque você não precisa configurar onde a ferramenta armazena as informações do ambiente virtual (pois é um valor padrão). Tudo que você precisa fazer é rodar o seguinte comando no Prompt de Comando.</p>
+
+<pre class="notranslate"><code>pip3 install virtualenvwrapper-win</code></pre>
+
+<p>Agora você pode criar um novo ambiente virtual com o comando <code>mkvirtualenv</code>.</p>
+
+<h3 id="Criando_um_ambiente_virtual">Criando um ambiente virtual</h3>
+
+<p>Uma vez que você tenha instalado <em>virtualenvwrapper</em> ou <em>virtualenvwrapper-win</em>, trabalhar com ambientes virtuais é bem parecido em todas as plataformas.</p>
+
+<p>Agora você pode criar um novo ambiente virtual com o comando <code>mkvirtualenv</code>. Ao executar esse comando, você verá o ambiente sendo configurado (o que você verá varia um pouco em cada plataforma). Quando o comando encerrar a configuração, o ambiente virtual estará ativo — você pode ver isso porque no topo do prompt (aquela barra de título do programa) estará escrito o nome do ambiente entre colchetes (abaixo nós mostramos como é a criação do ambiente no Ubuntu, mas o comando é igual para o Windows/macOS).</p>
+
+<pre class="notranslate"><code>$ mkvirtualenv my_django_environment
+
+Running virtualenv with interpreter /usr/bin/python3
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details
+(my_django_environment) ubuntu@ubuntu:~$</code>
+</pre>
+
+<p>Agora que você está em um ambiente virtual, você pode instalar Django e iniciar o desenvolvimento.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: De agora em diante, esse artigo (na verdade todo o módulo) está supondo que todos os comando serão executados em um ambiente virtual Python como o que configuramos acima.</p>
+</div>
+
+<h3 id="Usando_um_ambiente_virtual">Usando um ambiente virtual</h3>
+
+<p>Existem apenas alguns poucos comandos que você deveria conhecer (há mais comandos que você pode encontrar na documentação da ferramenta, porém, os comandos abaixo serão os que você usará regularmente):</p>
+
+<ul>
+ <li><code>deactivate</code> — Encerra o ambiente virtual Python corrente.</li>
+ <li><code>workon</code> — Lista ambientes virtuais disponíveis.</li>
+ <li><code>workon name_of_environment</code> — Ativa o ambiente virtual Python especificado.</li>
+ <li><code>rmvirtualenv name_of_environment</code> — Remove o ambiente especificado.</li>
+</ul>
+
+<h2 id="Instalando_o_Django">Instalando o Django</h2>
+
+<p>Após criar um ambiente virtual e usado o comando <code>workon</code> para ativá-lo, você pode usar <em>pip3 </em>para instalar o Django. </p>
+
+<pre class="brush: bash notranslate">pip3 install django
+</pre>
+
+<p>Você pode testar a instalação do Django executando o seguinte comando (isso apenas testa se o Python pode achar o módulo Django):</p>
+
+<pre class="brush: bash notranslate"># Linux/macOS
+python3 -m django --version
+ 2.1.5
+
+# Windows
+py -3 -m django --version
+ 2.1.5
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Se o comando Windows acima não mostrar um módulo django, tente:</p>
+
+<pre class="brush: bash notranslate">py -m django --version</pre>
+
+<p>No Windows, os scripts <em>Python 3</em> são iniciados prefixando o comando com <code>py -3</code>, embora isso possa variar de acordo com sua instalação. Tente omitir o modificador <code>-3</code> se você encontrar algum problema com os comandos. No Linux/macOS, o comando é <code>python3</code>.</p>
+</div>
+
+<div class="warning">
+<p><strong>Importante</strong>: O resto deste <strong>módulo </strong>usa o comando <em>Linux</em>  para chamar o Python 3 (<code>python3</code>). Se você  está usando o Windows, substitua o prefixo por: <code>py -3</code></p>
+</div>
+
+<h2 id="Testando_sua_instalação">Testando sua instalação</h2>
+
+<p>O teste acima funciona, mas não é muito divertido. Um teste mais interessante é criar o esqueleto de um projeto e vê-lo funcionando. Para fazer isso, para isso navegue em seu prompt de comando/terminal até o diretório que quer armazenar seus aplicativos Django. Crie uma pasta para seu site e navegue nela.</p>
+
+<pre class="brush: bash notranslate">mkdir django_test
+cd django_test
+</pre>
+
+<p>Agora você pode criar um novo site chamado "<em>mytestsite</em>" usando a ferramenta <strong>django-admin</strong>. Após criar o site você pode navegar dentro da pasta onde encontrará o script principal para gerenciar projetos, nomeado <strong>manage.py</strong>.</p>
+
+<pre class="brush: bash notranslate">django-admin startproject mytestsite
+cd mytestsite</pre>
+
+<p>Nós podemos rodar o <em>web server de desenvolvimento</em> dentro dessa pasta usando o <strong>manage.py</strong> e o comando <code>runserver</code>, como mostrado.</p>
+
+<pre class="brush: bash notranslate">$ python3 manage.py runserver
+Performing system checks...
+
+System check identified no issues (0 silenced).
+
+You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
+Run 'python manage.py migrate' to apply them.
+
+December 16, 2018 - 07:06:30
+Django version 2.1.5, using settings 'mytestsite.settings'
+Starting development server at http://127.0.0.1:8000/
+Quit the server with CONTROL-C.
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Acima foi mostrado o comando em Linux/macOS. Você já pode ignorar o aviso sobre "15 unapplied migration(s)"!</p>
+</div>
+
+<p>Uma vez que o servidor está operando, você pode acessar o site colocando a seguinte URL no seu navegador local:<code>http://127.0.0.1:8000/</code>. Você deveria ver um site como esse:<br>
+ <img alt="Django Skeleton App Homepage - Django 2.0" src="https://mdn.mozillademos.org/files/16288/Django_Skeleton_Website_Homepage_2_1.png" style="height: 714px; width: 806px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Agora você tem um ambiente de desenvolvimento em Django funcionando em seu computador.</p>
+
+<p>Na seção <em>Testando sua instalação </em>você viu brevemente como criar um website Django usando <code>django-admin startproject</code>, e executá-lo em seu navegador usando um web server de desenvolvimento (<code>python3 manage.py runserver</code>). No próximo artigo nós iremos expandir esse processo, construindo uma aplicação web simples, mas completa.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/intro/install/">Guia de Instalação Rápida</a> (documentação Django)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/install/">Como instalar Django — Guia completo</a> (documentação Django) - inclui informações para remover o Django</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/windows/">Como instalar Django no Windows</a> (documentação Django)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="https://developer.mozilla.org/pt-br/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Utilizando models</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/web_application_security">Segurança de aplicações web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/authentication/index.html b/files/pt-br/learn/server-side/django/authentication/index.html
new file mode 100644
index 0000000000..77535ae7ba
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/authentication/index.html
@@ -0,0 +1,692 @@
+---
+title: 'Tutorial Django Parte 8: Autenticação de usuário e permissões'
+slug: Learn/Server-side/Django/Authentication
+translation_of: Learn/Server-side/Django/Authentication
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Neste tutorial, mostraremos como permitir que os usuários efetuem login no seu site com suas próprias contas e como controlar o que eles podem fazer e ver com base em se eles estão ou não conectados e em suas permissões. Como parte desta demonstração, estenderemos o <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a> website, adicionando páginas de login e logout e páginas específicas do usuário e da equipe para visualizar os livros emprestados.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Conclua todos os tópicos do tutorial anterior, incluindo <a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Para entender como configurar e usar a autenticação e permissões de usuário.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_global">Visão global</h2>
+
+<p>O Django fornece um sistema de autenticação e autorização ("permissão"), construído sobre a estrutura da sessão discutida no <a href="/en-US/docs/Learn/Server-side/Django/Sessions">tutorial anterior</a>, que permite verificar as credenciais do usuário e definir quais ações cada usuário tem permissão para executar. A estrutura inclui modelos internos para <code>Users</code> e <code>Groups</code> (uma maneira genérica de aplicar permissões a mais de um usuário por vez), permissões/sinalizadores que designam se um usuário pode executar uma tarefa, formulários e exibições para efetuar logon em usuários e exibir ferramentas para restringir o conteúdo.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: De acordo com o Django, o sistema de autenticação pretende ser muito genérico e, portanto, não fornece alguns recursos fornecidos em outros sistemas de autenticação na web. Soluções para alguns problemas comuns estão disponíveis como pacotes de terceiros. Por exemplo, limitação de tentativas de login e autenticação contra terceiros (por exemplo, OAuth).</p>
+</div>
+
+<p>Neste tutorial, mostraremos como habilitar a autenticação do usuário no diretório <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a> website, crie suas próprias páginas de logon e logout, adicione permissões aos seus modelos e controle o acesso às páginas. Usaremos a autenticação/permissões para exibir listas de livros que foram emprestados para usuários e bibliotecários.</p>
+
+<p>O sistema de autenticação é muito flexível e você pode criar seus URLs, formulários, visualizações e modelos a partir do zero, se quiser, apenas chamando a API fornecida para efetuar login no usuário. No entanto, neste artigo, vamos usar as visualizações e formulários de autenticação "stock" do Django para nossas páginas de logon e logout. Ainda precisamos criar alguns modelos, mas isso é bem fácil.</p>
+
+<p>Também mostraremos como criar permissões e verificar o status e as permissões de login nas visualizações e nos modelos.</p>
+
+<h2 id="Ativando_a_autenticação">Ativando a autenticação</h2>
+
+<p>A autenticação foi ativada automaticamente quando <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">criamos o esqueleto do site</a> (no tutorial 2), para que você não precise fazer mais nada neste momento.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: A configuração necessária foi feita para nós quando criamos o aplicativo usando o comando <code>django-admin startproject</code>. As tabelas de banco de dados para usuários e permissões de modelo foram criadas quando chamamos pela primeira vez <code>python manage.py migrate</code>.</p>
+</div>
+
+<p>A configuração está definida nas seções <code>INSTALLED_APPS</code> e <code>MIDDLEWARE</code> no settings.py (<strong>locallibrary/locallibrary/settings.py</strong>), como mostrado abaixo:</p>
+
+<pre class="brush: python notranslate">INSTALLED_APPS = [
+ ...
+<strong>    'django.contrib.auth', </strong>#Core authentication framework and its default models.
+<strong>    'django.contrib.contenttypes', #</strong>Django content type system (allows permissions to be associated with models).
+ ....
+
+MIDDLEWARE = [
+ ...
+<strong>    'django.contrib.sessions.middleware.SessionMiddleware',</strong> #Manages sessions across requests
+ ...
+<strong>    'django.contrib.auth.middleware.AuthenticationMiddleware',</strong> #Associates users with requests using sessions.
+ ....
+</pre>
+
+<h2 id="Criando_usuários_e_grupos">Criando usuários e grupos</h2>
+
+<p>Você já criou seu primeiro usuário quando olhamos para o <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">site Django admin</a> no tutorial 4 (este era um superusuário, criado com o comando <code>python manage.py createsuperuser)</code>. Nosso superusuário já está autenticado e tem todas as permissões, portanto, precisamos criar um usuário de teste para representar um usuário normal do site. Usaremos o site de administração para criar nossos grupos de bibliotecas de locais e logins de sites, pois é uma das maneiras mais rápidas de fazer isso.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Você também pode criar usuários programaticamente, conforme mostrado abaixo. Você precisaria fazer isso, por exemplo, se desenvolvesse uma interface para permitir que os usuários criassem seus próprios logins (você não deve conceder aos usuários acesso ao site de administração).</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.models import User
+
+# Create user and save to the database
+user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword')
+
+# Update fields and then save again
+user.first_name = 'John'
+user.last_name = 'Citizen'
+user.save()
+</pre>
+</div>
+
+<p>Abaixo, primeiro criaremos um grupo e depois um usuário. Embora ainda não tenhamos permissões para adicionar aos membros da nossa biblioteca, se precisarmos mais tarde, será muito mais fácil adicioná-los uma vez ao grupo do que individualmente a cada membro.</p>
+
+<p>Inicie o servidor de desenvolvimento e navegue até o site de administração em seu navegador da web local (<a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin/</a>). Entre no site usando as credenciais da sua conta de superusuário. O nível superior do site Admin exibe todos os seus modelos, classificados por "aplicativo Django". Na seção <strong>Autenticação e Autorização</strong>, você pode clicar nos links <strong>Usuários </strong>ou <strong>Grupos </strong>para ver seus registros existentes.</p>
+
+<p><img alt="Admin site - add groups or users" src="https://mdn.mozillademos.org/files/14091/admin_authentication_add.png" style="border-style: solid; border-width: 1px; display: block; height: 364px; margin: 0px auto; width: 661px;"></p>
+
+<p>Primeiro vamos criar um novo grupo para os membros da nossa biblioteca.</p>
+
+<ol>
+ <li>Clique no botão <strong>Adicionar</strong> (ao lado de Grupo) para criar um novo grupo; digite o <strong>Nome</strong> "Library Members" para o grupo.<img alt="Admin site - add group" src="https://mdn.mozillademos.org/files/14093/admin_authentication_add_group.png" style="border-style: solid; border-width: 1px; display: block; height: 561px; margin: 0px auto; width: 800px;"></li>
+ <li>Não precisamos de permissões para o grupo, então pressione <strong>SALVAR </strong>(você será direcionado para uma lista de grupos).</li>
+</ol>
+
+<p>Agora vamos criar um usuário:</p>
+
+<ol>
+ <li>Volte para a página inicial do site de administração</li>
+ <li>Clique no botão <strong>Adicionar </strong>ao lado de <em>Usuários </em>para abrir a caixa de diálogo <em>Adicionar usuário</em>.<img alt="Admin site - add user pt1" src="https://mdn.mozillademos.org/files/14095/admin_authentication_add_user_prt1.png" style="border-style: solid; border-width: 1px; display: block; height: 409px; margin: 0px auto; width: 800px;"></li>
+ <li>Digite um nome de <strong>usuário </strong>e uma <strong>senha/confirmação de senha</strong> adequados para o usuário de teste</li>
+ <li>Pressione <strong>SALVAR </strong>para criar o usuário.<br>
+ <br>
+ O site de administração criará o novo usuário e levará você imediatamente para uma tela Alterar usuário, na qual é possível alterar seu <strong>nome de usuário</strong> e adicionar informações aos campos opcionais do modelo de usuário. Esses campos incluem o nome, o sobrenome, o endereço de email e o status e as permissões do usuário (somente o sinalizador <strong>Ativo </strong>deve ser definido). Mais abaixo, você pode especificar os grupos e permissões do usuário e ver datas importantes relacionadas ao usuário (por exemplo, a data de ingresso e a última data de login).<img alt="Admin site - add user pt2" src="https://mdn.mozillademos.org/files/14097/admin_authentication_add_user_prt2.png" style="border-style: solid; border-width: 1px; display: block; height: 635px; margin: 0px auto; width: 800px;"></li>
+ <li>Na seção <em>Grupos</em>, selecione grupo de <strong>Library Members</strong> na lista de <em>Grupos disponíveis</em> e pressione a <strong>seta para a direita</strong> entre as caixas para movê-lo para a caixa <em>Grupos escolhidos</em>.<img alt="Admin site - add user to group" src="https://mdn.mozillademos.org/files/14099/admin_authentication_user_add_group.png" style="border-style: solid; border-width: 1px; display: block; height: 414px; margin: 0px auto; width: 933px;"></li>
+ <li>Não precisamos fazer mais nada aqui; basta selecionar <strong>SALVAR </strong>novamente, para ir para a lista de usuários.</li>
+</ol>
+
+<p>É isso aí! Agora você tem uma conta de "membro normal da biblioteca" que poderá usar nos testes (depois de implementarmos as páginas para permitir o login).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Você deve tentar criar outro usuário membro da biblioteca. Além disso, crie um grupo para bibliotecários e adicione um usuário a ele também!</p>
+</div>
+
+<h2 id="Configurando_suas_views_de_autenticação">Configurando suas views de autenticação</h2>
+
+<p>O Django fornece quase tudo que você precisa para criar páginas de autenticação para lidar com o login, logout e gerenciamento de senhas "out of the box". Isso inclui um mapeador de URL, visualizações e formulários, mas não inclui os modelos - precisamos criar os nossos!</p>
+
+<p>Nesta seção, mostramos como integrar o sistema padrão no site <em>LocalLibrary </em>e criar os modelos. Vamos colocá-los nos principais URLs do projeto.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Você não precisa usar nenhum desses códigos, mas é provável que queira, porque isso facilita muito as coisas. Você quase certamente precisará alterar o código de manipulação de formulários se alterar seu modelo de usuário (um tópico avançado!), Mas, mesmo assim, ainda poderá usar as funções padrão das views.</p>
+</div>
+
+<div class="note">
+<p><strong>Nota: </strong>Nesse caso, poderíamos colocar razoavelmente as páginas de autenticação, incluindo os URLs e modelos, dentro do nosso aplicativo de catálogo. No entanto, se tivéssemos vários aplicativos, seria melhor separar esse comportamento de login compartilhado e disponibilizá-lo em todo o site, e é isso que mostramos aqui!</p>
+</div>
+
+<h3 id="URLs_do_Projeto">URLs do Projeto</h3>
+
+<p>Adicione o seguinte à parte inferior do arquivo urls.py do projeto (<strong>locallibrary/locallibrary/urls.py</strong>):</p>
+
+<pre class="brush: python notranslate">#Add Django site authentication urls (for login, logout, password management)
+urlpatterns += [
+ path('accounts/', include('django.contrib.auth.urls')),
+]
+</pre>
+
+<p>Navegue até URL <a href="http://127.0.0.1:8000/accounts/">http://127.0.0.1:8000/accounts/</a> (observe a barra à direita!) e o Django mostrará um erro que não foi possível encontrar esse URL e listará todos os URLs que ele tentou. A partir disso, você pode ver os URLs que funcionarão, por exemplo:</p>
+
+<div class="note">
+<p><strong>Nota: </strong>O uso do método acima adiciona os seguintes URLs com nomes entre colchetes, que podem ser usados para reverter os mapeamentos de URL. Você não precisa implementar mais nada - o mapeamento de URL acima mapeia automaticamente os URLs mencionados abaixo.</p>
+
+<pre class="brush: python notranslate">accounts/ login/ [name='login']
+accounts/ logout/ [name='logout']
+accounts/ password_change/ [name='password_change']
+accounts/ password_change/done/ [name='password_change_done']
+accounts/ password_reset/ [name='password_reset']
+accounts/ password_reset/done/ [name='password_reset_done']
+accounts/ reset/&lt;uidb64&gt;/&lt;token&gt;/ [name='password_reset_confirm']
+accounts/ reset/done/ [name='password_reset_complete']</pre>
+</div>
+
+<p>Agora tente navegar para o URL de login (<a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a>). Isso falhará novamente, mas com um erro informando que estamos perdendo o modelo necessário (<strong>registration/login.html</strong>) no caminho de pesquisa do modelo. Você verá as seguintes linhas listadas na seção amarela na parte superior:</p>
+
+<pre class="brush: python notranslate">Exception Type: TemplateDoesNotExist
+Exception Value: <strong>registration/login.html</strong></pre>
+
+<p>A próxima etapa é criar um diretório de registro no caminho de pesquisa e adicionar o arquivo <strong>login.html</strong>.</p>
+
+<h3 id="Diretório_de_Templates">Diretório de Templates</h3>
+
+<p>Os URLs (e implicitamente, visualizações) que acabamos de adicionar esperam encontrar seus modelos associados em um diretório <strong>/registration/</strong> em algum lugar no caminho de pesquisa de modelos.</p>
+
+<p>Neste site, colocaremos nossas páginas HTML no diretório <strong>templates/registration/</strong>. Esse diretório deve estar no diretório raiz do projeto, ou seja, o mesmo diretório que a pasta <strong>catalog</strong> e <strong>locallibrary</strong>. Por favor, crie essas pastas agora.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Sua estrutura de pastas agora deve se parecer como abaixo:<br>
+ locallibrary (Django project folder)<br>
+    |_catalog<br>
+    |_locallibrary<br>
+    |_templates <strong>(new)</strong><br>
+                 |_registration</p>
+</div>
+
+<p>Para tornar esses diretórios visíveis para o carregador de modelos (ou seja, para colocar esse diretório no caminho de pesquisa de modelos), abra as configurações do projeto (<strong>/locallibrary/locallibrary/settings.py</strong>) e atualize o seção <code>TEMPLATES</code> linha <code>'DIRS'</code> como mostrado abaixo.</p>
+
+<pre class="brush: python notranslate">TEMPLATES = [
+ {
+ ...
+<strong> 'DIRS': [os.path.join(BASE_DIR, 'templates')],</strong>
+ 'APP_DIRS': True,
+ ...
+</pre>
+
+<h3 id="Template_de_login">Template de login</h3>
+
+<div class="warning">
+<p><strong>Importante</strong>: Os modelos de autenticação fornecidos neste artigo são uma versão muito básica/ligeiramente modificada dos modelos de login de demonstração do Django. Pode ser necessário personalizá-los para seu próprio uso!</p>
+</div>
+
+<p>Crie um novo arquivo HTML chamado <strong>/locallibrary/templates/registration/login.html</strong> e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+
+ {% if form.errors %}
+ &lt;p&gt;Your username and password didn't match. Please try again.&lt;/p&gt;
+ {% endif %}
+
+ {% if next %}
+ {% if user.is_authenticated %}
+    &lt;p&gt;Your account doesn't have access to this page. To proceed,
+    please login with an account that has access.&lt;/p&gt;
+  {% else %}
+    &lt;p&gt;Please login to see this page.&lt;/p&gt;
+  {% endif %}
+ {% endif %}
+
+ &lt;form method="post" action="{% url 'login' %}"&gt;
+ {% csrf_token %}
+ &lt;table&gt;
+ &lt;tr&gt;
+  &lt;td&gt;\{{ form.username.label_tag }}&lt;/td&gt;
+  &lt;td&gt;\{{ form.username }}&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+  &lt;td&gt;\{{ form.password.label_tag }}&lt;/td&gt;
+  &lt;td&gt;\{{ form.password }}&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+ &lt;input type="submit" value="login" /&gt;
+ &lt;input type="hidden" name="next" value="\{{ next }}" /&gt;
+ &lt;/form&gt;
+
+ {# Assumes you setup the password_reset view in your URLconf #}
+ &lt;p&gt;&lt;a href="{% url 'password_reset' %}"&gt;Lost password?&lt;/a&gt;&lt;/p&gt;
+
+{% endblock %}</pre>
+
+<p id="sect1">Este modelo compartilha algumas semelhanças com as que já vimos antes - estende nosso modelo base e substitui o bloco <code>content</code>. O restante do código é um código de manipulação de formulário bastante padrão, que discutiremos em um tutorial posterior. Por enquanto, tudo o que você precisa saber é que isso exibirá um formulário no qual é possível inserir seu nome de usuário e senha e que, se você inserir valores inválidos, será solicitado que você digite os valores corretos quando a página for atualizada.</p>
+
+<p>Navegue de volta para a página de login (<a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a>). Depois de salvar seu modelo, você verá algo assim:</p>
+
+<p><img alt="Library login page v1" src="https://mdn.mozillademos.org/files/14101/library_login.png" style="border-style: solid; border-width: 1px; display: block; height: 173px; margin: 0px auto; width: 441px;"></p>
+
+<p>Se você fizer login usando credenciais válidas, será redirecionado para outra página (por padrão, isso será <a href="http://127.0.0.1:8000/accounts/profile/">http://127.0.0.1:8000/accounts/profile/</a>). O problema é que, por padrão, o Django espera que, ao fazer o login, você deseje ser levado para uma página de perfil, o que pode ou não ser o caso. Como você ainda não definiu esta página, receberá outro erro!</p>
+
+<p>Abra as configurações do projeto (<strong>/locallibrary/locallibrary/settings.py</strong>) e adicione o texto abaixo na parte inferior. Agora, quando você faz login, deve ser redirecionado para a página inicial do site por padrão.</p>
+
+<pre class="brush: python notranslate"># Redirect to home URL after login (Default redirects to /accounts/profile/)
+LOGIN_REDIRECT_URL = '/'
+</pre>
+
+<h3 id="Template_de_logout">Template de logout</h3>
+
+<p>Se você navegar para o URL de logout (<a href="http://127.0.0.1:8000/accounts/logout/">http://127.0.0.1:8000/accounts/logout/</a>) você verá um comportamento estranho - seu usuário será desconectado com certeza, mas será direcionado para a pagina de logout do <strong>Admin</strong>. Não é isso que você deseja, apenas porque o link de login nessa página o leva para a tela de login do administrador (e está disponível apenas para usuários que têm a permissão <code>is_staff</code>).</p>
+
+<p>Crie e abra /<strong>locallibrary/templates/registration/logged_out.html</strong>. Copie o texto abaixo:</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;p&gt;Logged out!&lt;/p&gt;
+ &lt;a href="{% url 'login'%}"&gt;Click here to login again.&lt;/a&gt;
+{% endblock %}</pre>
+
+<p>Este modelo é muito simples. Ele apenas exibe uma mensagem informando que você foi desconectado e fornece um link que você pode pressionar para voltar à tela de login. Se você acessar o URL de logoff novamente, deverá ver esta página:</p>
+
+<p><img alt="Library logout page v1" src="https://mdn.mozillademos.org/files/14103/library_logout.png" style="border-style: solid; border-width: 1px; display: block; height: 169px; margin: 0px auto; width: 385px;"></p>
+
+<h3 id="Templates_para_reset_de_password">Templates para reset de password</h3>
+
+<p>O sistema de redefinição de senha padrão usa o email para enviar ao usuário um link de redefinição. Você precisa criar formulários para obter o endereço de email do usuário, enviar o email, permitir que ele insira uma nova senha e anotar quando todo o processo está completo.</p>
+
+<p>Os seguintes modelos podem ser usados como ponto de partida.</p>
+
+<h4 id="Formulário_para_reset_de_password">Formulário para reset de password</h4>
+
+<p>Este é o formulário usado para obter o endereço de email do usuário (para enviar o email de redefinição de senha). Crie <strong>/locallibrary/templates/registration/password_reset_form.html</strong> e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;form action="" method="post"&gt;
+ {% csrf_token %}
+ {% if form.email.errors %}
+ \{{ form.email.errors }}
+ {% endif %}
+ &lt;p&gt;\{{ form.email }}&lt;/p&gt;
+ &lt;input type="submit" class="btn btn-default btn-lg" value="Reset password"&gt;
+ &lt;/form&gt;
+{% endblock %}
+</pre>
+
+<h4 id="Password_reset_done">Password reset done</h4>
+
+<p>Este formulário é exibido após a coleta do seu endereço de email. Crie <strong>/locallibrary/templates/registration/password_reset_done.html</strong>, e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;p&gt;We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.&lt;/p&gt;
+{% endblock %}
+</pre>
+
+<h4 id="Password_reset_email">Password reset email</h4>
+
+<p>Este modelo fornece o texto do email em HTML que contém o link de redefinição que enviaremos aos usuários. Crie<strong> /locallibrary/templates/registration/password_reset_email.html</strong> e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: html notranslate">Someone asked for password reset for email \{{ email }}. Follow the link below:
+\{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
+</pre>
+
+<h4 id="Password_reset_confirm">Password reset confirm</h4>
+
+<p>É nesta página que você digita sua nova senha depois de clicar no link no e-mail de redefinição de senha. Crie <strong>/locallibrary/templates/registration/password_reset_confirm.html</strong> e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ {% if validlink %}
+ &lt;p&gt;Please enter (and confirm) your new password.&lt;/p&gt;
+ &lt;form action="" method="post"&gt;
+ {% csrf_token %}
+ &lt;table&gt;
+ &lt;tr&gt;
+ &lt;td&gt;\{{ form.new_password1.errors }}
+ &lt;label for="id_new_password1"&gt;New password:&lt;/label&gt;&lt;/td&gt;
+ &lt;td&gt;\{{ form.new_password1 }}&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td&gt;\{{ form.new_password2.errors }}
+ &lt;label for="id_new_password2"&gt;Confirm password:&lt;/label&gt;&lt;/td&gt;
+ &lt;td&gt;\{{ form.new_password2 }}&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td&gt;&lt;/td&gt;
+ &lt;td&gt;&lt;input type="submit" value="Change my password" /&gt;&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+ &lt;/form&gt;
+ {% else %}
+ &lt;h1&gt;Password reset failed&lt;/h1&gt;
+ &lt;p&gt;The password reset link was invalid, possibly because it has already been used. Please request a new password reset.&lt;/p&gt;
+ {% endif %}
+{% endblock %}
+</pre>
+
+<h4 id="Password_reset_complete">Password reset complete</h4>
+
+<p>Este é o último modelo de redefinição de senha, exibido para notificá-lo quando a redefinição de senha for bem-sucedida. Crie <strong>/locallibrary/templates/registration/password_reset_complete.html</strong> e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;The password has been changed!&lt;/h1&gt;
+ &lt;p&gt;&lt;a href="{% url 'login' %}"&gt;log in again?&lt;/a&gt;&lt;/p&gt;
+{% endblock %}</pre>
+
+<h3 id="Testando_as_novas_páginas_de_autenticação">Testando as novas páginas de autenticação</h3>
+
+<p>Agora que você adicionou a configuração da URL e criou todos esses modelos, as páginas de autenticação agora devem funcionar!</p>
+
+<p>Você pode testar as novas páginas de autenticação tentando fazer login e sair da sua conta de superusuário usando estes URLs:</p>
+
+<ul>
+ <li><a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a></li>
+ <li><a href="http://127.0.0.1:8000/accounts/logout/">http://127.0.0.1:8000/accounts/logout/</a></li>
+</ul>
+
+<p>Você poderá testar a funcionalidade de redefinição de senha no link na página de login. <strong>Esteja ciente de que o Django enviará apenas emails de redefinição para endereços (usuários) que já estão armazenados em seu banco de dados!</strong></p>
+
+<div class="note">
+<p><strong>Nota</strong>: O sistema de redefinição de senha exige que seu site suporte e-mail, que está além do escopo deste artigo, portanto esta parte ainda não funcionará. Para permitir o teste, coloque a seguinte linha no final do seu arquivo settings.py. Isso registra todos os emails enviados ao console (para que você possa copiar o link de redefinição de senha do console).</p>
+
+<pre class="brush: python notranslate">EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+</pre>
+
+<p>Para mais informações, veja <a href="https://docs.djangoproject.com/en/2.1/topics/email/">Sending email</a> (Django docs).</p>
+</div>
+
+<h2 id="Testando_contra_usuários_autenticados">Testando contra usuários autenticados</h2>
+
+<p>Esta seção analisa o que podemos fazer para controlar seletivamente o conteúdo que o usuário vê, com base em se está logado ou não.</p>
+
+<h3 id="Testando_nos_templates">Testando nos templates</h3>
+
+<p>Você pode obter informações sobre o usuário conectado no momento em modelos com a variável de template <code>\{{ user }}</code> (isso é adicionado ao contexto do template por padrão quando você configura o projeto como fizemos em nosso esqueleto).</p>
+
+<p>Normalmente você primeiro testará contra a variável de template <code>\{{ user.is_authenticated }}</code> para determinar se o usuário está qualificado para ver conteúdo específico. Para demonstrar isso, em seguida, atualizaremos nossa barra lateral para exibir um link "Login" se o usuário estiver desconectado e um link "Logout" se estiverem conectados.</p>
+
+<p>Abra o template base (<strong>/locallibrary/catalog/templates/base_generic.html</strong>) e copie o texto a seguir no bloco <code>sidebar</code>, imediatamente antes da template tag <code>endblock</code>.</p>
+
+<pre class="brush: html notranslate"> &lt;ul class="sidebar-nav"&gt;
+
+ ...
+
+ <strong>{% if user.is_authenticated %}</strong>
+ &lt;li&gt;User: <strong>\{{ user.get_username }}</strong>&lt;/li&gt;
+ &lt;li&gt;&lt;a href="{% url 'logout'%}?next=\{{request.path}}"&gt;Logout&lt;/a&gt;&lt;/li&gt;
+ <strong>{% else %}</strong>
+ &lt;li&gt;&lt;a href="{% url 'login'%}?next=\{{request.path}}"&gt;Login&lt;/a&gt;&lt;/li&gt;
+ <strong>{% endif %} </strong>
+ &lt;/ul&gt;</pre>
+
+<p>Como você pode ver, usamos template tags <code>if</code>-<code>else</code>-<code>endif</code> para exibir condicionalmente o texto com base em <code>\{{ user.is_authenticated }}</code> ser verdadeiro. Se o usuário estiver autenticado, sabemos que temos um usuário válido, por isso chamamos <code>\{{ user.get_username }}</code><strong> </strong>para exibir o nome deles.</p>
+
+<p>Criamos os URLs dos links de logon e logout usando a template tag <code>url</code> e os nomes das respectivas configurações de URL. Observe também como anexamos <code>?next=\{{request.path}}</code> no final dos URLs. O que isso faz é adicionar um parâmetro de URL a seguir, contendo o endereço (URL) da página atual, ao final do URL vinculado. Após o usuário ter efetuado login/logout com sucesso, as visualizações usarão este valor "<code>next</code>" para redirecionar o usuário de volta à página em que ele clicou pela primeira vez no link de logon/logout.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Experimente! Se você estiver na página inicial e clicar em Login/Logout na barra lateral, depois que a operação for concluída, você deverá voltar à mesma página.</p>
+</div>
+
+<h3 id="Testando_nas_views">Testando nas views</h3>
+
+<p>Se você estiver usando views baseadas em funções, a maneira mais fácil de restringir o acesso a suas funções é aplicando o decorator <code>login_required</code> à sua função view, como mostrado abaixo. Se o usuário estiver logado, seu código de exibição será executado normalmente. Se o usuário não estiver conectado, isso será redirecionado para o URL de login definido nas configurações do projeto.(<code>settings.LOGIN_URL</code>), passando o caminho absoluto atual como o <code>next</code> no parametro da URL. Se o usuário conseguir fazer login, ele retornará a esta página, mas desta vez autenticado.</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.decorators import login_required
+
+@login_required
+def my_view(request):
+ ...</pre>
+
+<div class="note">
+<p><strong>Nota:</strong> Você pode fazer o mesmo tipo de coisa manualmente testando em<code>request.user.is_authenticated</code>, mas o decorator é muito mais conveniente!</p>
+</div>
+
+<p>Da mesma forma, a maneira mais fácil de restringir o acesso a usuários logados em suas visualizações baseadas em classe é derivar de <code>LoginRequiredMixin</code>. Você precisa declarar esse mixin primeiro na lista de superclasses, antes da classe de visualização principal.</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin
+
+class MyView(LoginRequiredMixin, View):
+ ...</pre>
+
+<p>Isso tem exatamente o mesmo comportamento de redirecionamento que o decorator <code>login_required</code>. Você também pode especificar um local alternativo para redirecionar o usuário se ele não estiver autenticado (<code>login_url</code>), e um nome de parâmetro de URL em vez de "<code>next</code>" para inserir o caminho absoluto atual (<code>redirect_field_name</code>).</p>
+
+<pre class="brush: python notranslate">class MyView(LoginRequiredMixin, View):
+ login_url = '/login/'
+ redirect_field_name = 'redirect_to'
+</pre>
+
+<p>Para detalhes adicionais, consulte o <a href="https://docs.djangoproject.com/en/2.1/topics/auth/default/#limiting-access-to-logged-in-users">Django docs here</a>.</p>
+
+<h2 id="Exemplo_-_listando_os_livros_do_usuário_atual">Exemplo - listando os livros do usuário atual</h2>
+
+<p>Agora que sabemos como restringir uma página a um usuário específico, vamos criar uma visualização dos livros que o usuário atual emprestou.</p>
+
+<p>Infelizmente, ainda não temos como os usuários emprestarem livros! Portanto, antes que possamos criar a lista de livros, primeiro estenderemos o modelo <code>BookInstance</code> para suportar o conceito de empréstimo e usar o aplicativo Django Admin para emprestar vários livros ao nosso usuário de teste.</p>
+
+<h3 id="Models">Models</h3>
+
+<p>Primeiro, teremos que possibilitar que os usuários tenham um <code>BookInstance</code> emprestado (já temos um <code>status</code> e uma data <code>due_back</code>, mas ainda não temos nenhuma associação entre esse modelo e um usuário. Vamos criar um usando um campo <code>ForeignKey</code> (one-to-many). Também precisamos de um mecanismo fácil para testar se um livro emprestado está vencido.</p>
+
+<p>Abra <strong>catalog/models.py</strong>, e importe o model <code>User</code> de <code>django.contrib.auth.models</code> (adicione isso logo abaixo da linha de importação anterior na parte superior do arquivo, para <code>User</code> estar disponível para o código subsequente que faz uso dele):</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.models import User
+</pre>
+
+<p>Em seguida, adicione o campo <code>borrower</code> para o modelo <code>BookInstance</code>:</p>
+
+<pre class="brush: python notranslate">borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
+</pre>
+
+<p>Enquanto estamos aqui, vamos adicionar uma propriedade que podemos chamar de nossos modelos para saber se uma instância específica de um livro está atrasada. Embora possamos calcular isso no próprio modelo, usando uma <a href="https://docs.python.org/3/library/functions.html#property">property</a> como mostrado abaixo será muito mais eficiente.</p>
+
+<p>Adicione isso em algum lugar perto da parte superior do arquivo:</p>
+
+<pre class="brush: python notranslate">from datetime import date</pre>
+
+<p class="brush: python">Agora adicione a seguinte definição de propriedade a classe <code>BookInstance</code>:</p>
+
+<pre class="brush: python notranslate">@property
+def is_overdue(self):
+ if self.due_back and date.today() &gt; self.due_back:
+ return True
+ return False</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Primeiro, verificamos se <code>due_back</code> está vazio antes de fazer uma comparação. Um campo <code>due_back</code> vazio faria com que o Django gerasse um erro em vez de mostrar a página: valores vazios não são comparáveis. Isso não é algo que gostaríamos que nossos usuários experimentassem!</p>
+</div>
+
+<p>Agora que atualizamos nossos modelos, precisaremos fazer novas migrações no projeto e aplicá-las:</p>
+
+<pre class="brush: bash notranslate">python3 manage.py makemigrations
+python3 manage.py migrate
+</pre>
+
+<h3 id="Admin">Admin</h3>
+
+<p>Agora abra <strong>catalog/admin.py</strong>, e adicione o campo <code>borrower</code> para a classe <code>BookInstanceAdmin</code> em ambos os <code>list_display</code> e o <code>fieldsets</code> como mostrado abaixo. Isso tornará o campo visível na seção Admin, permitindo atribuir um <code>User</code> para um <code>BookInstance</code> quando necessário.</p>
+
+<pre class="brush: python notranslate">@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    list_display = ('book', 'status'<strong>, 'borrower'</strong>, 'due_back', 'id')
+    list_filter = ('status', 'due_back')
+
+    fieldsets = (
+        (None, {
+            'fields': ('book','imprint', 'id')
+        }),
+        ('Availability', {
+            'fields': ('status', 'due_back'<strong>,'borrower'</strong>)
+        }),
+    )</pre>
+
+<h3 id="Emprestando_alguns_livros">Emprestando alguns livros</h3>
+
+<p>Agora que é possível emprestar livros para um usuário específico, vá e empreste vários <code>BookInstance</code>. Defina o campo <code>borrowed</code> para o usuário de teste, faça o <code>status</code> "On loan", e defina datas de vencimento no futuro e no passado.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Não detalharemos o processo, pois você já sabe como usar o site Admin!</p>
+</div>
+
+<h3 id="Na_view_loan">Na view loan</h3>
+
+<p>Agora, adicionaremos uma view para obter a lista de todos os livros que foram emprestados ao usuário atual. Usaremos a mesma view de lista genérica baseada em classe com a qual estamos familiarizados, mas desta vez também importaremos e derivaremos de <code>LoginRequiredMixin</code>, para que apenas um usuário conectado possa chamar essa visualização. Também optaremos por declarar um <code>template_name</code>, em vez de usar o padrão, pois podemos ter algumas listas diferentes de registros BookInstance, com diferentes visualizações e modelos.</p>
+
+<p>Adicione o seguinte a <strong>catalog/views.py</strong>:</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin
+
+class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
+ """Generic class-based view listing books on loan to current user."""
+ model = BookInstance
+ template_name ='catalog/bookinstance_list_borrowed_user.html'
+ paginate_by = 10
+
+ def get_queryset(self):
+ return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')</pre>
+
+<p>Para restringir nossa consulta apenas ao objeto <code>BookInstance</code> para o usuário atual, reimplementamos <code>get_queryset()</code> como mostrado abaixo. Observe que "o" is the stored code for "on loan" (emprestado) e nós pedimos pela data <code>due_back</code> para que os itens mais antigos sejam exibidos primeiro.</p>
+
+<h3 id="URL_conf_para_livros_on_loan_emprestado">URL conf para livros on loan (emprestado)</h3>
+
+<p>Agora abra <strong>/catalog/urls.py</strong> e adicione um <code>path()</code> apontando para a visualização acima (você pode copiar o texto abaixo no final do arquivo).</p>
+
+<pre class="brush: python notranslate">urlpatterns += [
+ path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
+]</pre>
+
+<h3 id="Template_para_livros_on_loan_emprestado">Template para livros on loan (emprestado)</h3>
+
+<p>Agora, tudo o que precisamos fazer para esta página é adicionar um modelo. Primeiro, crie o arquivo de modelo <strong>/catalog/templates/catalog/bookinstance_list_borrowed_user.html</strong> e forneça o seguinte conteúdo:</p>
+
+<pre class="brush: python notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Borrowed books&lt;/h1&gt;
+
+ {% if bookinstance_list %}
+ &lt;ul&gt;
+
+ {% for bookinst in bookinstance_list %}
+ &lt;li class="{% if bookinst.is_overdue %}text-danger{% endif %}"&gt;
+ &lt;a href="{% url 'book-detail' bookinst.book.pk %}"&gt;\{{bookinst.book.title}}&lt;/a&gt; (\{{ bookinst.due_back }})
+ &lt;/li&gt;
+ {% endfor %}
+ &lt;/ul&gt;
+
+ {% else %}
+ &lt;p&gt;There are no books borrowed.&lt;/p&gt;
+ {% endif %}
+{% endblock %}</pre>
+
+<p>Este modelo é muito semelhante ao que criamos anteriormente para os objetos <code>Book</code> e <code>Author</code>. A única coisa "nova" aqui é que verificamos o método que adicionamos no modelo <code>(bookinst.is_overdue</code>) e use-o para alterar a cor dos itens em atraso.</p>
+
+<p>Quando o servidor de desenvolvimento estiver em execução, agora você poderá visualizar a lista de um usuário conectado no seu navegador em <a href="http://127.0.0.1:8000/catalog/mybooks/">http://127.0.0.1:8000/catalog/mybooks/</a>. Experimente isso com o usuário conectado e desconectado (no segundo caso, você deve ser redirecionado para a página de login).</p>
+
+<h3 id="Adicione_a_lista_à_barra_lateral">Adicione a lista à barra lateral</h3>
+
+<p>O último passo é adicionar um link para esta nova página na barra lateral. Colocaremos isso na mesma seção em que exibimos outras informações para o usuário conectado.</p>
+
+<p>Abra o template base (<strong>/locallibrary/catalog/templates/base_generic.html</strong>) e adicione a linha em negrito à barra lateral, como mostrado.</p>
+
+<pre class="brush: python notranslate"> &lt;ul class="sidebar-nav"&gt;
+ {% if user.is_authenticated %}
+ &lt;li&gt;User: \{{ user.get_username }}&lt;/li&gt;
+<strong> &lt;li&gt;&lt;a href="{% url 'my-borrowed' %}"&gt;My Borrowed&lt;/a&gt;&lt;/li&gt;</strong>
+ &lt;li&gt;&lt;a href="{% url 'logout'%}?next=\{{request.path}}"&gt;Logout&lt;/a&gt;&lt;/li&gt;
+ {% else %}
+ &lt;li&gt;&lt;a href="{% url 'login'%}?next=\{{request.path}}"&gt;Login&lt;/a&gt;&lt;/li&gt;
+ {% endif %}
+ &lt;/ul&gt;
+</pre>
+
+<h3 id="Com_o_que_se_parece">Com o que se parece?</h3>
+
+<p>Quando qualquer usuário estiver conectado, ele verá o link <em>My Borrowed</em> na barra lateral e a lista de livros exibida abaixo (o primeiro livro não tem data de vencimento, que é um bug que esperamos corrigir em um tutorial posterior!) .</p>
+
+<p><img alt="Library - borrowed books by user" src="https://mdn.mozillademos.org/files/14105/library_borrowed_by_user.png" style="border-style: solid; border-width: 1px; display: block; height: 215px; margin: 0px auto; width: 530px;"></p>
+
+<h2 id="Permissões">Permissões</h2>
+
+<p>As permissões são associadas aos modelos e definem as operações que podem ser executadas em uma instância de modelo por um usuário que possui a permissão. Por padrão, o Django automaticamente fornece permissões de adição, alteração e exclusão para todos os modelos, o que permite que usuários com permissões executem as ações associadas através do site de administração. Você pode definir suas próprias permissões para modelos e concedê-las a usuários específicos. Você também pode alterar as permissões associadas a diferentes instâncias do mesmo modelo.</p>
+
+<p>Testar permissões nas views e templates é muito semelhante ao teste no status de autenticação (e, na verdade, testar uma permissão também testa a autenticação).</p>
+
+<h3 id="Models_2">Models</h3>
+
+<p>A definição de permissões é feita na seção "<code>class Meta</code>" do modelo, usando o campo <code>permissions</code>. Você pode especificar quantas permissões você precisar em uma tupla, cada permissão sendo definida em uma tupla aninhada que contém o nome da permissão e o valor de exibição da permissão. Por exemplo, podemos definir uma permissão para permitir que um usuário marque que um livro foi retornado como mostrado:</p>
+
+<pre class="brush: python notranslate">class BookInstance(models.Model):
+ ...
+  class Meta:
+  ...
+<strong> permissions = (("can_mark_returned", "Set book as returned"),) </strong> </pre>
+
+<p>Poderíamos então atribuir a permissão a um grupo "Librarian" no site do administrador.</p>
+
+<p>Abra <strong>catalog/models.py</strong>, e adicione a permissão como mostrado acima. Você ira precisar atualizar seus <em>migrations</em> (execute <code>python3 manage.py makemigrations</code> e <code>python3 manage.py migrate</code>) para atualizar o banco de dados apropriadamente.</p>
+
+<h3 id="Templates">Templates</h3>
+
+<p>As permissões do usuário atual são armazenadas em uma variável de modelo chamada <code>\{{ perms }}</code>. Você pode verificar se o usuário atual tem uma permissão específica usando o nome da variável específica no "aplicativo" associado ao Django — e.g. <code>\{{ perms.catalog.can_mark_returned }}</code> será <code>True</code> se o usuário tiver essa permissão, caso contrário,  <code>False</code>. Normalmente testamos a permissão usando a template tag <code>{% if %}</code> como mostrado:</p>
+
+<pre class="brush: python notranslate">{% if perms.catalog.can_mark_returned %}
+ &lt;!-- We can mark a BookInstance as returned. --&gt;
+  &lt;!-- Perhaps add code to link to a "book return" view here. --&gt;
+{% endif %}
+</pre>
+
+<h3 id="Views">Views</h3>
+
+<p>As permissões podem ser testadas na exibição de funções usando o decorator <code>permission_required</code> ou em uma view baseada em classe usando o <code>PermissionRequiredMixin</code>. O padrão e o comportamento são os mesmos da autenticação de login, embora, é claro, você possa razoavelmente precisar adicionar várias permissões.</p>
+
+<p>Função view decorator:</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.decorators import permission_required
+
+@permission_required('catalog.can_mark_returned')
+@permission_required('catalog.can_edit')
+def my_view(request):
+ ...</pre>
+
+<p>Um permission-required mixin para class-based views.</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.mixins import PermissionRequiredMixin
+
+class MyView(PermissionRequiredMixin, View):
+ permission_required = 'catalog.can_mark_returned'
+ # Or multiple permissions
+ permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
+ # Note that 'catalog.can_edit' is just an example
+ # the catalog application doesn't have such permission!</pre>
+
+<h3 id="Exemplo">Exemplo</h3>
+
+<p>Não atualizaremos a <em>LocalLibrary </em>aqui; talvez no próximo tutorial!</p>
+
+<h2 id="Desafie-se">Desafie-se</h2>
+
+<p>No início deste artigo, mostramos como criar uma página para o usuário atual, listando os livros emprestados. O desafio agora é criar uma página semelhante que seja visível apenas para bibliotecários, que exiba <em>todos </em>os livros que foram emprestados e que inclua o nome de cada mutuário.</p>
+
+<p>Você deve seguir o mesmo padrão da outra view. A principal diferença é que você precisará restringir a visualização apenas a bibliotecários. Você pode fazer isso com base no fato de o usuário ser um membro da equipe (decorator da função: <code>staff_member_required</code>, variável do template: <code>user.is_staff</code>) mas recomendamos que você use a permissão <code>can_mark_returned</code> e <code>PermissionRequiredMixin</code>, conforme descrito na seção anterior.</p>
+
+<div class="warning">
+<p><strong>Importante</strong>: Lembre-se de não usar seu superusuário para testes baseados em permissões (as verificações de permissão sempre retornam verdadeiras para os superusuários, mesmo que uma permissão ainda não tenha sido definida!). Em vez disso, crie um usuário bibliotecário e adicione o recurso necessário.</p>
+</div>
+
+<p>Quando terminar, sua página será semelhante à captura de tela abaixo.</p>
+
+<p><img alt="All borrowed books, restricted to librarian" src="https://mdn.mozillademos.org/files/14115/library_borrowed_all.png" style="border-style: solid; border-width: 1px; display: block; height: 283px; margin: 0px auto; width: 500px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Excelente trabalho — Você criou um site no qual os membros da biblioteca podem fazer login e ver seu próprio conteúdo e que os bibliotecários (com as permissões corretas) podem usar para visualizar todos os livros emprestados e seus devedores. No momento, ainda estamos apenas visualizando conteúdo, mas os mesmos princípios e técnicas são usadas quando você deseja começar a modificar e adicionar dados.</p>
+
+<p>Em nosso próximo artigo, veremos como você pode usar os formulários Django para coletar entradas do usuário, e então começar a modificar alguns dos nossos dados armazenados.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/auth/">Autenticação de usuário no Django</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/auth/default//">Usando o sistema (default) de Autenticação do Django</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/intro/#decorating-class-based-views">Introdução a views baseadas em classe &gt; Decorating class-based views</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Usando models</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Authentication">Tutorial Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/forms/index.html b/files/pt-br/learn/server-side/django/forms/index.html
new file mode 100644
index 0000000000..dda15b7657
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/forms/index.html
@@ -0,0 +1,679 @@
+---
+title: 'Tutorial Django Parte 9: Trabalhando com formulários'
+slug: Learn/Server-side/Django/Forms
+translation_of: Learn/Server-side/Django/Forms
+---
+<div> {{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Neste tutorial, vamos te mostrar como trabalhar com formulários HTML no Django e, em particular, a maneira mais fácil de programar formulários para criar, alterar e excluir instâncias de modelos. Como parte desta demonstração, vamos estender o site da <a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_website_biblioteca_local">BibliotecaLocal</a> para que bibliotecários possam renovar reservas e criar, alterar e excluir autores usando nossos próprios formulários em vez do "admin" do Django.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Completar todos os tópicos anteriores deste tutorial, incluindo <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions">Django Tutorial Parte 8: Autenticação e Permissões de Usuário</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>
+ <p>Entender como programar formulários para obter informações dos usuários e atualizar a base de dados. Entender como as <em>views</em> genéricas de edição de formulários baseadas em classes podem simplificar a criação de formulários para trabalhar com um único <em>model</em>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Geral">Visão Geral</h2>
+
+<p>Um <a href="/pt-BR/docs/Web/Guide/HTML/Forms">Formulário HTML</a> é um grupo de um ou mais campos/<em>widgets</em> em uma página web, que podem ser utilizados para coletar informações dos usuários para submetê-las a um servidor. Formulários são um mecanismo flexível para coletar input de usuário porque há <em>widgets</em> adequados para entrada de variados tipos de dados, incluindo caixas de texto, caixas de seleção, botões radiais, seletores de data etc. Formulários são também um meio relativamente seguro de compartilhar dados com o servidor, pois nos permitem enviar dados em requisições <code>POST</code> com proteção contra ataques maliciosos <strong>CSRF</strong> (<em><strong>Cross-Site Request Forgery</strong></em> - em inglês, falsificação de solicitação entre sites).</p>
+
+<p>Apesar de ainda não termos criado formulários até o momento neste tutorial, já os encontramos na página do Django Admin — por exemplo, a captura de tela abaixo mostra um formulário para editar um dos nossos modelos de <a href="/pt-br/docs/Learn/Server-side/Django/Models">Livros</a>, incluindo algumas listas de seleção e editores de texto.</p>
+
+<p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<p>Trabalhar com formulários pode ser complicado! Desenvolvedores precisam escrever HTML para o formulário, validar e limpar dados submetidos ao servidor (e possivelmente também ao navegador), programar mensagens de erro no formulário para informar o usuário de quaisquer preenchimentos inválidos, lidar com os dados quando enviados com sucesso e, finalmente, mostrar ao usuário algum indicativo de sucesso. Os <em>Django Forms </em>adiantam boa parte desses passos disponibilizando uma estrutura que permite a você definir formulários e seus campos programaticamente, e então utilizar esses objetos tanto para gerar o código HTML do formulário como para cuidar de boa parte da validação e interação de usuário.</p>
+
+<p>Neste tutorial, vamos te mostrar alguns dos métodos para se criar e trabalhar com formulários e, em particular, como as <em>views</em> genéricas de edição de formulários podem reduzir significativamente o seu trabalho ao criar formulários para manipular seus <em>models</em>. Ao longo do caminho, vamos estender nossa aplicação <em>LocalLibrary </em>adicionando um formulário que permita que bibliotecários renovem locações de livros, e vamos construir páginas para criar, alterar e excluir livros e autores (reproduzindo uma versão básica do formulário exibido acima para alterar livros).</p>
+
+<h2 id="Formulários_HTML">Formulários HTML</h2>
+
+<p>Antes de mais nada, um breve resumo de <a href="/pt-br/docs/Learn/HTML/Forms">Formulários HTML</a>. Considere um formulário HTML simples, com um único campo de texto para entrada do nome de uma "equipe", e sua respectiva legenda:</p>
+
+<p><img alt="Simple name field example in HTML form" src="https://mdn.mozillademos.org/files/14117/form_example_name_field.png" style="border-style: solid; border-width: 1px; display: block; height: 44px; margin: 0px auto; width: 399px;"></p>
+
+<p>O formulário é definido no HTML como uma coleção de elementos dentro das tags <code>&lt;form&gt;...&lt;/form&gt;</code>, contendo ao menos um elemento <code>input</code> do tipo <code>type="submit"</code>.</p>
+
+<pre class="brush: html">&lt;form action="/team_name_url/" method="post"&gt;
+    &lt;label for="team_name"&gt;Enter name: &lt;/label&gt;
+    &lt;input id="team_name" type="text" name="name_field" value="Default name for team."&gt;
+    &lt;input type="submit" value="OK"&gt;
+&lt;/form&gt;</pre>
+
+<p>Apesar de aqui nós termos um único para inserir o nome da equipe, um formulário pode ter qualquer quantidade de outros elementos de entrada e suas respectivas legendas. O atributo <code>type</code> de um campo define que tipo de widget será exibido. O <code>name</code> e o <code>id</code> de cada campo são utilizados para identificá-lo no JavaScript/CSS/HTML, enquanto <code>value</code> define o valor preenchido inicialmente no campo quando ele é exibido pela primeira vez. A legenda da equipe é especificada usando a tag <code>label</code> (veja "Enter name" na imagem acima), com um atributo <code>for</code> contendo o valor de <code>id</code> do <code>input</code> a ele associado.</p>
+
+<p>A entrada <code>submit</code> será exibida como um botão (por padrão) que pode ser pressionado pelo usuário para enviar ao servidor os dados preenchidos em todos os outros elementos de entrada naquele formulário (neste caso, apenas <code>team_name</code>). Os atributos do formulário definem o método HTTP (<code>method</code>) utilizado para enviar os dados e o destino para esses dados no servidor (<code>action</code>):</p>
+
+<ul>
+ <li><code>action</code>: O recurso/URL para onde os dados devem ser enviados para processamento quando o formulário é enviado. Se isso não estiver configurado (ou configurado para uma string vazia), o formulário será enviado de volta para URL da página atual.</li>
+ <li><code>method</code>: O método HTTP method utilizado para enviar os dados: <em>post</em> or <em>get</em>.
+ <ul>
+ <li>O método <code>POST</code> deve sempre ser utilizado se os dados forem resultar em uma alteração no banco de dados do servidor, pois é mais resistente a ataques de falsificação de solicitação entre sites.</li>
+ <li>O método <code>GET</code> deve ser utilizado somente para formulários que não alteram dados de usuário (um formulário de busca, por exemplo). Ele é recomendado para quando você quiser poder favoritar ou compartilhar a URL.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>O papel do servidor é primeiramente carregar o estado inicial do formulário — seja contendo campos em branco ou preenchidos com valores iniciais. Após o usuário clicar no botão de envio, o servidor receberá do navegador os dados do formulário preenchido e deverá validar as informações. Se o formulário contiver dados inválidos, o servidor deverá exibir o formulário novamente, desta vez já com os valores enviados pelo usuário nos campos preenchidos corretamente, mais uma mensagem descrevendo o problema encontrado em cada campo considerado inválido. Uma vez que o servidor receber uma requisição do formulário com todos os dados válidos, poderá exercer a ação apropriada (por exemplo, salvar os dados, retornar o resultado de uma busca, subir um arquivo etc) e então notificar o usuário.</p>
+
+<p>Como você pode imaginar, as ações de criar o HTML, validar os dados recebidos, re-exibir os dados enviados com mensagens de erro se necessário e realizar a operação desejada com os dados válidos podem todas tomar bastante tempo e esforço. O Django torna tudo isso muito mais fácil, adiantando parte do "trabalho braçal" e código repetitivo!</p>
+
+<h2 id="Processo_de_manipulação_de_formulários_Django">Processo de manipulação de formulários Django</h2>
+
+<p>O tratamento de formulários do Django usa todas as mesmas técnicas que aprendemos nos tutoriais anteriores (para exibir informações sobre nossos modelos): a view recebe uma solicitação, executa todas as ações necessárias, incluindo a leitura de dados dos modelos, gera e retorna uma página HTML ( de um modelo, no qual passamos um <em>contexto </em>que contém os dados a serem exibidos). O que torna as coisas mais complicadas é que o servidor também precisa processar dados fornecidos pelo usuário e exibir novamente a página se houver algum erro.</p>
+
+<p>Um fluxograma do processo de como o Django lida com solicitações de formulário é mostrado abaixo, começando com uma solicitação para uma página contendo um formulário (mostrado em verde).</p>
+
+<p><img alt="Updated form handling process doc." src="https://mdn.mozillademos.org/files/14205/Form%20Handling%20-%20Standard.png" style="display: block; height: 569px; margin: 0px auto; width: 800px;"></p>
+
+<p>Com base no diagrama acima, as principais coisas que o manuseio de formulários do Django faz são:</p>
+
+<ol>
+ <li>Exiba o formulário padrão na primeira vez em que for solicitado pelo usuário
+ <ul>
+ <li>O formulário pode conter campos em branco (por exemplo, se você estiver criando um novo registro) ou pode ser preenchido previamente com valores iniciais (por exemplo, se você estiver alterando um registro ou tiver valores iniciais padrão úteis).</li>
+ <li>O formulário é referido como <em>unbound</em> neste momento, porque não está associado a nenhum dado inserido pelo usuário (embora possa ter valores iniciais).</li>
+ </ul>
+ </li>
+ <li>Receba dados de uma solicitação de envio e vincule-os ao formulário.
+ <ul>
+ <li>Vincular dados ao formulário significa que os dados inseridos pelo usuário e quaisquer erros estão disponíveis quando precisamos exibir novamente o formulário.</li>
+ </ul>
+ </li>
+ <li>Limpe e valide os dados.
+ <ul>
+ <li>A limpeza dos dados executa a higienização da entrada (por exemplo, removendo caracteres inválidos que podem ser usados para enviar conteúdo malicioso ao servidor) e os converte em tipos consistentes de Python.</li>
+ <li>A validação verifica se os valores são apropriados para o campo (por exemplo, estão no período certo, não são muito curtos ou muito longos etc.)</li>
+ </ul>
+ </li>
+ <li>Se algum dado for inválido, exiba novamente o formulário, desta vez com valores preenchidos pelo usuário e mensagens de erro para os campos problemáticos.</li>
+ <li>Se todos os dados forem válidos, execute as ações necessárias (por exemplo, salve os dados, envie e envie por e-mail, retorne o resultado de uma pesquisa, faça o upload de um arquivo etc.)</li>
+ <li>Quando todas as ações estiverem concluídas, redirecione o usuário para outra página.</li>
+</ol>
+
+<p>O Django fornece várias ferramentas e abordagens para ajudá-lo nas tarefas detalhadas acima. O mais fundamental é a classe <code>Form</code>, o que simplifica a geração de HTML de formulário e a limpeza/validação de dados. Na próxima seção, descreveremos como os formulários funcionam usando o exemplo prático de uma página para permitir que os bibliotecários renovem os livros.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Entendendo como <code>Form</code> é usado para ajudá-lo quando discutirmos as classes de estrutura de formulário mais "de alto nível" do Django.</p>
+</div>
+
+<h2 id="Renew-book_form_usando_uma_function_view">Renew-book form usando uma function view</h2>
+
+<p>Em seguida, adicionaremos uma página para permitir que os bibliotecários renovem os livros emprestados. Para fazer isso, criaremos um formulário que permita aos usuários inserir um valor de data. Preencheremos o campo com um valor inicial três semanas a partir da data atual (o período normal de empréstimo) e adicionaremos alguma validação para garantir que o bibliotecário não possa inserir uma data no passado ou uma data muito distante no futuro. Quando uma data válida for inserida, nós a escreveremos no registro atual no campo <code>BookInstance.due_back</code>.</p>
+
+<p>O exemplo usará uma function-based view e uma classe <code>Form</code>. As seções a seguir explicam como os formulários funcionam e as alterações que você precisa fazer em nosso projeto <em>LocalLibrary</em>.</p>
+
+<h3 id="Form">Form</h3>
+
+<p>A classe <code>Form</code> é o coração do sistema de manipulação de formulários do Django. Ele especifica os campos no formulário, seu layout, exibe widgets, rótulos, valores iniciais, valores válidos e (uma vez validadas) as mensagens de erro associadas a campos inválidos. A classe também fornece métodos para renderizar-se em modelos usando formatos predefinidos (tabelas, listas etc.) ou para obter o valor de qualquer elemento (habilitando a renderização manual refinada).</p>
+
+<h4 id="Declarando_um_Form">Declarando um Form</h4>
+
+<p>A sintaxe da declaração para um <code>Form</code> é muito semelhante ao da declaração de um <code>Model</code>, e compartilha os mesmos tipos de campo (e alguns parâmetros semelhantes). Isso faz sentido porque, em ambos os casos, precisamos garantir que cada campo lide com os tipos corretos de dados, seja restrito a dados válidos e tenha uma descrição para exibição/documentação.</p>
+
+<p>Os dados do formulário são armazenados no arquivo forms.py de um aplicativo, dentro do diretório do aplicativo. Crie e abra o arquivo <strong>locallibrary/catalog/forms.py</strong>. Para criar um <code>Form</code>, nós importamos a biblioteca <code>forms</code>, deriva da classe <code>Form</code>, e declarar os campos do formulário. Uma classe de formulário muito básica para nosso formulário de renovação de livros da biblioteca é mostrada abaixo - adicione-a ao seu novo arquivo:</p>
+
+<pre class="brush: python">from django import forms
+
+class RenewBookForm(forms.Form):
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+</pre>
+
+<h4 id="Campos_do_Form">Campos do Form</h4>
+
+<p>Nesse caso, temos um único <code><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#datefield">DateField</a></code> para inserir a data de renovação que será renderizada em HTML com um valor em branco, o valor padrão da label "<em>Renewal date:</em>", e algum texto de ajuda: "<em>Enter a date between now and 4 weeks (default 3 weeks).</em>" Como nenhum dos outros argumentos opcionais é especificado, o campo aceita datas usando o <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#django.forms.DateField.input_formats">input_formats</a>: YYYY-MM-DD (2016-11-06), MM/DD/YYYY (02/26/2016), MM/DD/YY (10/25/16), e será renderizado usando o padrão <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#widget">widget</a>: <a href="https://docs.djangoproject.com/en/2.1/ref/forms/widgets/#django.forms.DateInput">DateInput</a>.</p>
+
+<p>Existem muitos outros tipos de campos de formulário que você reconhecerá amplamente por sua semelhança com as classes de campo de modelo equivalentes: <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#booleanfield"><code>BooleanField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#charfield"><code>CharField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#choicefield"><code>ChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#typedchoicefield"><code>TypedChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#datefield"><code>DateField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#datetimefield"><code>DateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#decimalfield"><code>DecimalField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#durationfield"><code>DurationField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#emailfield"><code>EmailField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#filefield"><code>FileField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#filepathfield"><code>FilePathField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#floatfield"><code>FloatField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#imagefield"><code>ImageField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#integerfield"><code>IntegerField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#genericipaddressfield"><code>GenericIPAddressField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#multiplechoicefield"><code>MultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#typedmultiplechoicefield"><code>TypedMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#nullbooleanfield"><code>NullBooleanField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#regexfield"><code>RegexField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#slugfield"><code>SlugField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#timefield"><code>TimeField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#urlfield"><code>URLField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#uuidfield"><code>UUIDField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#combofield"><code>ComboField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#multivaluefield"><code>MultiValueField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#splitdatetimefield"><code>SplitDateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#modelmultiplechoicefield"><code>ModelMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#modelchoicefield"><code>ModelChoiceField</code></a>.</p>
+
+<p>Os argumentos comuns à maioria dos campos estão listados abaixo (estes têm valores padrão sensíveis):</p>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#required">required</a>: Se <code>True</code>, o campo não pode ser deixado em branco ou receber um valor <code>None</code>. Os campos são obrigatórios por padrão, então você deve definir <code>required=False</code> para permitir valores em branco no formulário.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#label">label</a>: O label a ser usado ao renderizar o campo em HTML. Se um <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#label">label</a> não for especificado, o Django criará um a partir do nome do campo colocando em maiúscula a primeira letra e substituindo sublinhados por espaços (e.g. <em>Renewal date</em>).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#label-suffix">label_suffix</a>: Por padrão, dois pontos são exibidos após o rótulo (e.g. Renewal date<strong>:</strong>). Esse argumento permite especificar um sufixo diferente contendo outros caractere(s).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#initial">initial</a>: O valor inicial para o campo quando o formulário é exibido.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#widget">widget</a>: O widget de exibição a ser usado.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#help-text">help_text</a> (como visto no exemplo acima): Texto adicional que pode ser exibido em formulários para explicar como usar o campo.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#error-messages">error_messages</a>: Uma lista de mensagens de erro para o campo. Você pode substituí-los por suas próprias mensagens, se necessário.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#validators">validators</a>: Uma lista de funções que serão chamadas no campo quando validadas.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#localize">localize</a>:Permite a localização da entrada de dados do formulário (consulte o link para obter mais informações).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#disabled">disabled</a>: O campo é exibido, mas seu valor não pode ser editado se este for <code>True</code>. O padrão é <code>False</code>.</li>
+</ul>
+
+<h4 id="Validação">Validação</h4>
+
+<p>O Django fornece vários locais onde você pode validar seus dados. A maneira mais fácil de validar um único campo é substituir o método <code>clean_<strong>&lt;fieldname&gt;</strong>()</code> para o campo que você deseja verificar. Por exemplo, podemos validar esse valor inserido <code>renewal_date</code> daqui a quatro semanas, implementando <code>clean_<strong>renewal_date</strong>()</code> como mostrado abaixo.</p>
+
+<p>Atualize seu arquivo forms.py para ficar assim:</p>
+
+<pre class="brush: python"><strong>import datetime</strong>
+
+from django import forms
+<strong>from django.core.exceptions import ValidationError
+from django.utils.translation import ugettext_lazy as _
+</strong>
+class RenewBookForm(forms.Form):
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+<strong>    def clean_renewal_date(self):
+        data = self.cleaned_data['renewal_date']
+
+        # Check if a date is not in the past.
+        if data &lt; datetime.date.today():
+            raise ValidationError(_('Invalid date - renewal in past'))
+
+        # Check if a date is in the allowed range (+4 weeks from today).
+        if data &gt; datetime.date.today() + datetime.timedelta(weeks=4):
+            raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+        # Remember to always return the cleaned data.
+        return data</strong></pre>
+
+<p>Há duas coisas importantes a serem observados. A primeira é que temos nossos dados usando <code>self.cleaned_data['renewal_date']</code> e que nós retornaremos esses dados ou não podemos alterá-lo no final da função. Este passo nos leva a dados "limpos" e higienizados de potencialmente inseguro usando os validadores de entrada padrão e convertidos para o tipo padrão correto para os dados (neste caso, um objeto Python <code>datetime.datetime</code>).</p>
+
+<p>O segundo ponto é que, se um valor cai fora da nossa gama que levanta um <code>ValidationError</code>, especificando o texto de erro que deseja exibir no formulário se um valor inválido for inserido. Os exemplos acima também envolvem este texto em um dos <a href="https://docs.djangoproject.com/en/2.1/topics/i18n/translation/">Django's translation functions</a> <code>ugettext_lazy()</code> (importado como <code>_()</code>), que é uma boa prática se você quiser traduzir o seu site mais tarde.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Existem muitos outros exemplos e métodos para validar os forms <a href="https://docs.djangoproject.com/en/2.1/ref/forms/validation/">Form e field validation</a> (Django docs). Por exemplo, nos casos em que você tem vários campos que dependem uns dos outros, você pode substituir a função <a href="https://docs.djangoproject.com/en/2.1/ref/forms/api/#django.forms.Form.clean">Form.clean()</a> e novamente levantar uma <code>ValidationError</code>.</p>
+</div>
+
+<p>Isso é tudo que necessitamos para o form neste exemplo?</p>
+
+<h3 id="Configuração_da_URL">Configuração da URL</h3>
+
+<p>Antes de criar nossa view, vamos adicionar a configuração da URL para a pagina <em>renew-books</em>. Copie a seguinte configuração para o final do aquivo <strong>locallibrary/catalog/urls.py</strong>.</p>
+
+<pre class="brush: python">urlpatterns += [
+ path('book/&lt;uuid:pk&gt;/renew/', views.renew_book_librarian, name='renew-book-librarian'),
+]</pre>
+
+<p>A configuração da URL irá redirecionar as URLs com o formato <strong>/catalog/book/<em>&lt;bookinstance id&gt;</em>/renew/</strong> para a função chamada <code>renew_book_librarian()</code> em <strong>views.py</strong>, e enviar o id  <code>BookInstance</code> como parâmetro nomeado <code>pk</code>. O padrão corresponde apenas se <code>pk</code> estiver com a formatação <code>uuid</code> correta.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Podemos citar nos nossos dados capturados na URL "<code>pk</code>" qualquer coisa que quisermos, porque nós temos o controle completo sobra a função view (nós não estamos usando uma view detail genérica, onde se espera os parâmetros com um certo nome). Contudo, a abreviação <code>pk</code> para "chave primária", é uma convenção razoável para uso!</p>
+</div>
+
+<h3 id="View">View</h3>
+
+<p>Como discutido no <a href="#django_form_handling_process">processo de manipulação de formulários Django </a>acima, a view renderizará o formulário padrão chamado pela primeira vez e então retorná-lo com mensagens de erro se os dados forem inválidos, ou processar os dados e redirecioná-lo para uma nova página se os dados forem válidos.A fim de executar essas ações diferentes, a view deve ser capas de saber se está sendo chamada pela primeira vez para renderizar o form padrão ou um subsequente para a validação dos dados.</p>
+
+<p>Para forms que usam uma solicitação <code>POST</code> para enviar informações para o servidor, o padrão mais comum para a view é testar se o tipo de solicitação é <code>POST</code> (<code>if request.method == 'POST':</code>) para identificar requisições válidas de formulário e <code>GET</code> (usando uma condição <code>else</code>) para identificar a requisição de criação do form inicial. Se você deseja enviar seus dados usando uma reuquisição <code>GET</code> uma abordagem típica para identificar se é a primeira ou subsequente requisição é ler os dados do formulário (por exemplo, ler um valor oculto no form).</p>
+
+<p>O processo de renovação de livros será gravado em nosso banco de dados, portanto, por convenção, usamos a abordagem de requisição <code>POST</code>. O fragmento de código abaixo mostra o padrão (bem padrão) para esse tipo de exibição de função.</p>
+
+<pre class="brush: python">import datetime
+
+from django.shortcuts import render, get_object_or_404
+from django.http import HttpResponseRedirect
+from django.urls import reverse
+
+from catalog.forms import RenewBookForm
+
+def renew_book_librarian(request, pk):
+    book_instance = get_object_or_404(BookInstance, pk=pk)
+
+    # If this is a POST request then process the Form data
+<strong>    if request.method == 'POST':</strong>
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        <strong>if form.is_valid():</strong>
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_instance.due_back = form.cleaned_data['renewal_date']
+            book_instance.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form.
+<strong>    else:</strong>
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
+
+ context = {
+ 'form': form,
+ 'book_instance': book_instance,
+ }
+
+    return render(request, 'catalog/book_renew_librarian.html', context)</pre>
+
+<p>Primeiro, importamos nosso formulário (<code>RenewBookForm</code>) e outros objetos/métodos úteis usados no corpo da função <em>view</em>:</p>
+
+<ul>
+ <li><code><a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#get-object-or-404">get_object_or_404()</a></code>: Retorna um objeto especificado de um modelo com base em seu valor de chave primária, e gera uma exceção <code>Http404</code> (não encontrada) se o registro não existir. </li>
+ <li><code><a href="https://docs.djangoproject.com/en/2.1/ref/request-response/#django.http.HttpResponseRedirect">HttpResponseRedirect</a></code>: Isso cria um redirecionamento para uma URL especificada (código de status HTTP 302). </li>
+ <li><code><a href="https://docs.djangoproject.com/en/2.1/ref/urlresolvers/#django.urls.reverse">reverse()</a></code>: Isso gera uma URL a partir de uma configuração de nome de URL e um conjunto de argumentos. É o equivalente em Python da tag <code>url</code> que usamos em nossos <em>templates</em>.</li>
+ <li><code><a href="https://docs.python.org/3/library/datetime.html">datetime</a></code>: Uma biblioteca Python para a manipulação de dadas e tempo.</li>
+</ul>
+
+<p>Na <em>view</em>, primeiro usamos o argumento <code>pk</code> em <code>get_object_or_404()</code> para obter o <code>BookInstance</code> atual (se isso não existir, a <em>view</em> será imediatamente encerrada e a página exibirá um erro "não encontrada"). Se essa não for uma solicitação <code>POST</code> (manipulada pela cláusula <code>else</code>) criamos o formulário padrão passando o valor <code>initial</code> para o campo <code>renewal_date</code> (como mostrado abaixo em negrito, isso é, 3 semanas a partir da data atual). </p>
+
+<pre class="brush: python"> book_instance = get_object_or_404(BookInstance, pk=pk)
+
+    # If this is a GET (or any other method) create the default form
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(<strong>weeks=3</strong>)
+        <strong>form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})</strong>
+
+ context = {
+ 'form': form,
+ 'book_instance': book_instance,
+ }
+
+    return render(request, 'catalog/book_renew_librarian.html', context)</pre>
+
+<p>Depois de criar o <em>form</em>, chamamos <code>render()</code> para criar a página HTML, especificando o <em>template</em> e o <em>context</em> que contém o nosso <em>form</em>. Nesse caso, o <em>context</em> também contem nosso <code>BookInstance</code>, que usaremos no <em>template</em> para fornecer informações sobre o livro que estamos renovando.</p>
+
+<p>No entenato, se essa for uma solicitação <code>POST</code> , criamos nosso objeto <code>form</code> e prenchemos com dados da requisição. Esse processo é chamado <em>"binding"</em> e permite validar o formulário. Em seguida, verificamos se o formulário é válido, que executa todo o código de validação em todos os campos — incluindo o código genérico para verificar se nosso campo de data é realmente uma data válida e a função específica <code>clean_renewal_date()</code> do nosso formulário para verificar se a data está na faixa certa. </p>
+
+<pre class="brush: python">    book_instance = get_object_or_404(BookInstance, pk=pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+<strong>        form = RenewBookForm(request.POST)</strong>
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_instance.due_back = form.cleaned_data['renewal_date']
+            book_instance.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+ context = {
+ 'form': form,
+ 'book_instance': book_instance,
+ }
+
+    return render(request, 'catalog/book_renew_librarian.html', context)</pre>
+
+<p>Se o formulário não é válido, chamamos <code>render()</code> novamente, mas dessa vez o valor passado de <em>form</em> no <em>context</em> incluirá mensagens de erro. </p>
+
+<p>Se o formulário é válido, então podemos começar a utilizar os dados, acessando-o por meio do atributo<code>form.cleaned_data</code> (Ex. <code>data = form.cleaned_data['renewal_date']</code>). Aqui, apenas salvamos os dados no atributo <code>due_back</code> do objeto <code>BookInstance</code> associado.</p>
+
+<div class="warning">
+<p><strong>Importante</strong>: Embora você também possa acessar os dados do formulário diretamente por meio do <em>request</em> (por exemplo, <code>request.POST['renewal_date']</code> ou <code>request.GET['renewal_date']</code> se utilizando requisição GET), isso NÃO é recomendado. O dado limpo é "higienizado", validado, e convertido em tipo compatível com Python.</p>
+</div>
+
+<p>A estapa final da manipulação de formulário na parte da <em>view</em> é redirecionar para outra página, geralmente uma página de "êxito". Nesse caso, usamos  <code>HttpResponseRedirect</code> e <code>reverse()</code> para redirecionar para a <em>view </em>chamada <code>'all-borrowed'</code> (isso foi criado como desafio em <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Tutorial Django Parte 8: Autenticação de usuário e permissões</a>). Se você não criou está página considere redirecionar para a página principal na URL '/').</p>
+
+<p>Isso é tudo que é necessário para a manipulação do formulario, mas ainda precisamo restringir o acesso a <em>view</em> aos bibliotecários. Provavelmente devemos criar uma nova permissão em <code>BookInstance</code> ("<code>can_renew</code>"), mas, para simplificar as coisa aqui, apenas usamos o <em>decorator </em>da função<em>,  </em><code>@permission_required</code> com nossa permissão existente  <code>can_mark_returned</code>.</p>
+
+<p>A <em>view</em> final, é portanto, como mostrado abaixo. Por favor, copie isso na parte inferior de <strong>locallibrary/catalog/views.py</strong>.</p>
+
+<pre><strong>import datetime
+
+from django.contrib.auth.decorators import permission_required</strong>
+from django.shortcuts import get_object_or_404
+from django.http import HttpResponseRedirect
+from django.urls import reverse
+
+from catalog.forms import RenewBookForm
+
+<strong>@permission_required('catalog.can_mark_returned')</strong>
+def renew_book_librarian(request, pk):
+    """View function for renewing a specific BookInstance by librarian."""
+    book_instance = get_object_or_404(BookInstance, pk=pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_instance.due_back = form.cleaned_data['renewal_date']
+            book_instance.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form.
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
+
+ context = {
+ 'form': form,
+ 'book_instance': book_instance,
+ }
+
+    return render(request, 'catalog/book_renew_librarian.html', context)
+</pre>
+
+<h3 id="O_template">O <em>template</em></h3>
+
+<p>Crie o <em>template</em> mencionado na <em>view</em> (<strong>/catalog/templates/catalog/book_renew_librarian.html</strong>) e copie o código abaixo nele:</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Renew: \{{ book_instance.book.title }}&lt;/h1&gt;
+ &lt;p&gt;Borrower: \{{ book_instance.borrower }}&lt;/p&gt;
+ &lt;p{% if book_instance.is_overdue %} class="text-danger"{% endif %}&gt;Due date: \{{ book_instance.due_back }}&lt;/p&gt;
+
+<strong> &lt;form action="" method="post"&gt;
+ {% csrf_token %}
+  &lt;table&gt;
+ \{{ form.as_table }}
+ &lt;/table&gt;
+ &lt;input type="submit" value="Submit"&gt;
+ &lt;/form&gt;</strong>
+{% endblock %}</pre>
+
+<p>A maior parte disso será totalmente familiar dos tutoriais anteriores. Estendemos o <em>template</em> base e então redefinimos o bloco <em>content</em>. Somos capazes de referenciar  <code>\{{ book_instance }}</code> (e suas variáveis) porque foi passado no objeto <em>context</em> na função <code>render()</code>, e nós as usamos para listar o título do livro, tomador do empréstimo, e a data de devolução original.</p>
+
+<p>O código do formulário é relativamente simples. Primeiro, declaramos a tag <code>form</code>, especificando onde o formulário deve ser submetido (<code>action</code>) e o <code>method</code> para submeter os dados (nesse caso, um "HTTP POST") — se você lembrar da visão geral de <a href="#HTML_forms">Formulários HTML</a> na parte superior da página, uma <code>action</code> vazia, como mostrada, significa que os dados do formulário serão postados de volta para a URL atual da página (que é o que queremos!). Dentro das tags, definimos a entrada <code>submit</code>, que um usuário pode apertar para submeter os dados. O <code>{% csrf_token %}</code> adicionado apenas dentro das tags do formulário é parte da proteção de falsificação ente sites (cross-site forgery protection) do  Django.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Adicione o <code>{% csrf_token %}</code> para todos os <em>templates </em>Django que você cria que utiliza <code>POST</code> para submeter dados. Isso reduzirá a chance de que os formulários sejam invadidos por usuários maliciosos.</p>
+</div>
+
+<p>Tudo que resta é  a variável <code>\{{ form }}</code> do <em>template</em>, que passamos para o <em>template</em> no dicionário <em>context</em>. Talvez, sem supresa, quando usado como mostrado, isto fornece a renderização padrão de todos os campos do formulário, incluindo seus <em>labels</em>, <em>widgets</em> e texto de ajuda —  a renderização é como mostrado abaixo:</p>
+
+<pre class="brush: html">&lt;tr&gt;
+  &lt;th&gt;&lt;label for="id_renewal_date"&gt;Renewal date:&lt;/label&gt;&lt;/th&gt;
+  &lt;td&gt;
+  &lt;input id="id_renewal_date" name="renewal_date" type="text" value="2016-11-08" required&gt;
+  &lt;br&gt;
+  &lt;span class="helptext"&gt;Enter date between now and 4 weeks (default 3 weeks).&lt;/span&gt;
+  &lt;/td&gt;
+&lt;/tr&gt;
+</pre>
+
+<div class="note">
+<p><strong>Nota:</strong> Talvez não seja óbvio porque temos apenas um campo, mas, por padrão, todo campo é definido em sua própria linha de tabela. Essa mesma renderização é fornecida se você referenciar a váriavel de <em>template</em> <code>\{{ form.as_table }}</code>.</p>
+</div>
+
+<p>Se você fosse inserir uama data inválida, você também obteria uma lista dos erros renderizados na página (mostrado em negrito abaixo).</p>
+
+<pre class="brush: html">&lt;tr&gt;
+  &lt;th&gt;&lt;label for="id_renewal_date"&gt;Renewal date:&lt;/label&gt;&lt;/th&gt;
+  &lt;td&gt;
+<strong>  &lt;ul class="errorlist"&gt;
+  &lt;li&gt;Invalid date - renewal in past&lt;/li&gt;
+  &lt;/ul&gt;</strong>
+  &lt;input id="id_renewal_date" name="renewal_date" type="text" value="2015-11-08" required&gt;
+  &lt;br&gt;
+  &lt;span class="helptext"&gt;Enter date between now and 4 weeks (default 3 weeks).&lt;/span&gt;
+ &lt;/td&gt;
+&lt;/tr&gt;</pre>
+
+<h4 id="Outras_maneiras_de_usar_variável_de_formulário_de_template">Outras maneiras de usar variável de formulário de <em>template</em></h4>
+
+<p>Usando <code>\{{ form.as_table }}</code> como mostrado acima, cada campo é renderizado como uma linha da tabela. Você também pode renderizar cada campo como um item da lista (usando <code>\{{ form.as_ul }}</code> ) como um parágrafo (usando <code>\{{ form.as_p }}</code>).</p>
+
+<p>Também é possível ter controle completo sobre a renderização de cada parte do formulário, indexando suas propriedades usando notação de ponto. Assim, por exemplo, podemos acessar vários itens separados pelo nosso campo <code>renewal_date</code>:</p>
+
+<ul>
+ <li><code>\{{ form.renewal_date }}:</code> O campo todo.</li>
+ <li><code>\{{ form.renewal_date.errors }}</code>: A lista de erros.</li>
+ <li><code>\{{ form.renewal_date.id_for_label }}</code>: O id do <em>label</em>.</li>
+ <li><code>\{{ form.renewal_date.help_text }}</code>: O texto de ajuda do campo.</li>
+</ul>
+
+<p>Para mais exemplos de como renderizar formulários manualmente em <em>templates </em>e fazer loop nos campos de <em>templates</em>, veja <a href="https://docs.djangoproject.com/en/2.1/topics/forms/#rendering-fields-manually">Trabalhando com formulários &gt; Renderizando campos manualmente</a> (Django docs).</p>
+
+<h3 id="Testando_a_página">Testando a página</h3>
+
+<p>Se você aceitou o "desafio" em <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Tutorial Django Parte 8: Autenticação de usuário e permissões</a> você terá uma lista de todos os livros emprestados na biblioteca, que é visível apenas aos funcionários da biblioteca. Podemos adicionar um <em>link</em> para nossa página de renovação ao lado de cada item, usando o código de modelo abaixo.</p>
+
+<pre class="brush: html">{% if perms.catalog.can_mark_returned %}- &lt;a href="{% url 'renew-book-librarian' bookinst.id %}"&gt;Renew&lt;/a&gt; {% endif %}</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Lembre que seu login de teste precisará ter a permissão  "<code>catalog.can_mark_returned</code>" para acessar a página de renovação de livro (talvez use sua conta de superusuário).</p>
+</div>
+
+<p>Você pode, alternativamente, construir manualmente uma URL de teste como esta — <a href="http://127.0.0.1:8000/catalog/book/&lt;bookinstance id>/renew/">http://127.0.0.1:8000/catalog/book/<em>&lt;bookinstance_id&gt;</em>/renew/</a> (um id válido de <em>bookinstance</em> pode ser obtido navegando para a página de detalhes de um livro em sua biblioteca, e copiando o campo<code>id</code>).</p>
+
+<h3 id="Com_o_que_se_parece">Com o que se parece?</h3>
+
+<p>Se você tiver sucesso, o formulário padrão será semelhante a este:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14209/forms_example_renew_default.png" style="border-style: solid; border-width: 1px; display: block; height: 292px; margin: 0px auto; width: 680px;"></p>
+
+<p>O formulário com um valor inválido inserido terá a seguinte aparência:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14211/forms_example_renew_invalid.png" style="border-style: solid; border-width: 1px; display: block; height: 290px; margin: 0px auto; width: 658px;"></p>
+
+<p>A lista de todos os livros com o link de renovação será assim:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14207/forms_example_renew_allbooks.png" style="border-style: solid; border-width: 1px; display: block; height: 256px; margin: 0px auto; width: 613px;"></p>
+
+<h2 id="ModelForms">ModelForms</h2>
+
+<p>Criar uma classe<code>Form</code> usando a abordagem descrita acima é muito flexível, permitindo criar qualquer tipo de página de formulário que você desejar e associá-la a qualquer modelo ou modelos.</p>
+
+<p>Contudo, se você só precisa de um formulário para mapear os campos de um único modelo, então seu modelo já definirá a maioria das informações que vocÊ precisa em seu formulário: campos, rótulos, texto de ajuda, etc. Em vez de recriar as definições do modelo em seu formulário, é mais fácil usar a classe auxiliar <a href="https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/">ModelForm</a> para criar o formulário a partir do seu modelo. Esse <code>ModelForm</code> pode ser usado em suas <em>views</em> exatamente da mesma maneira como um <code>Form</code> comum.</p>
+
+<p>Uma <code>ModelForm</code> contém o mesmo campo que nossa <code>RenewBookForm</code> original, como mostrado abaixo. Tudo que você precisa fazer para criar o formulário é adicionar <code>class Meta</code> com o <code>model</code> (<code>BookInstance</code>) associado e uma lista dos <code>fields</code> do modelo a serem incluídos no formulário (você pode incluir todos os campos usando <code>fields = '__all__'</code>, ou pode usar <code>exclude</code> (em vez de <code>fields</code>) para especificar os campos do modelo a não incluir).</p>
+
+<pre class="brush: python">from django.forms import ModelForm
+
+from catalog.models import BookInstance
+
+class RenewBookModelForm(ModelForm):
+<strong> class Meta:
+ model = BookInstance
+ fields = ['due_back']</strong>
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Isso pode não parecer muito mais simples do que apenas usar um <code>Form</code> (e não é nesse caso, porque temos apenas um campo). No entanto, se você tiver muitos campos, isso pode reduzir a quantidade de código significativamente!</p>
+</div>
+
+<p>O restante das informações vem das definições de campo do modelo (ex. rótulos, <em>widgets</em>, texdo de ajuda, mensagens de erro). Se isso não for suficiente, então podemos substituí-los em nossa <code>class Meta</code>, especificando um dicionário contendo o campo para mudar e seu novo valor. Por exemplo, neste formulário podemos querer um rótulo para nosso campo de "<em>Renewal date</em>" (em vez do padrão baseado no padrão com base no nome do campo: <em>Due Back</em>), e também queremos que nosso campo de ajuda seja específico para esse caso de uso. A <code>Meta</code> abaixo mostra como substituir esses campos, e você pode definir <code>widgets</code> and <code>error_messages</code> da mesma forma, se os padrões não forem suficientes.</p>
+
+<pre class="brush: python">class Meta:
+ model = BookInstance
+ fields = ['due_back']
+<strong> labels = {'due_back': _('New renewal date')}
+ help_texts = {'due_back</strong><strong>': _('Enter a date between now and 4 weeks (default 3).')} </strong>
+</pre>
+
+<p>Para adicionar validação você pode usar  a mesma abordagem como uma <code>Form</code> normal — você define uma função chamada <code>clean_<em>field_name</em>()</code> e <em>raise</em> a exceção <code>ValidationError</code> para valores inválidos. A única diferença em relação ao nosso <em>form </em>original é que o campo do modelo é chamdo <code>due_back</code> e não "<code>renewal_date</code>". Essa mudança é necessária pois o campo correspondente em <code>BookInstance</code> é chamado <code>due_back</code>. </p>
+
+<pre class="brush: python">from django.forms import ModelForm
+
+from catalog.models import BookInstance
+
+class RenewBookModelForm(ModelForm):
+<strong>    def clean_due_back(self):
+       data = self.cleaned_data['due_back</strong><strong>']
+
+  # Check if a date is not in the past.
+       if data &lt; datetime.date.today():
+           raise ValidationError(_('Invalid date - renewal in past'))
+
+       <strong># Check if a date is in the allowed range (+4 weeks from today).</strong>
+       if data &gt; datetime.date.today() + datetime.timedelta(weeks=4):
+           raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+       # Remember to always return the cleaned data.
+       return data
+</strong>
+ class Meta:
+ model = BookInstance
+ fields = ['due_back']
+ labels = {'due_back': _('Renewal date')}
+ help_texts = {'due_back': _('Enter a date between now and 4 weeks (default 3).')}
+</pre>
+
+<p>A classe <code>RenewBookModelForm</code> acima agora é funcionalmente equivalente a nossa original <code>RenewBookForm</code>. Você poderia importar e usar onde quer que você use <code>RenewBookForm</code> desde que você também atualize o nome da variável do formulário correspondente de <code>renewal_date</code> para <code>due_back</code> como na segunda declaração do formulário: <code>RenewBookModelForm(initial={'due_back': proposed_renewal_date}</code>.</p>
+
+<h2 id="Views_genéricas_de_edição">Views genéricas de edição</h2>
+
+<p>O algoritmo de manipulação de formulários que usamos em nosso exemplo de função <em>view</em> acima, representa um padrão extremamente comum nas <em>views</em> de edição de formulário. Django abstrai grande parte desse "<em>boilerplate</em>" (trabalho repetitivo) para você, criando <a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/">views genéricas de edição</a> para views de criação, edição e exclusão baseadas em modelos. Não apenas lidam com o comportamento de visualização, mas também criam automaticamente para você a classe de formulário (uma <code>ModelForm</code>) a partir do modelo.</p>
+
+<div class="note">
+<p><strong>Nota: </strong>Além das <em>views</em> de edição descritas aqui, há também uma classe <a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/#formview">FormView</a>, que fica em algum lugar entre nossa função <em>view</em> e outra <em>view</em> genérica em termos de "flexibilidade" vs "esforço de codificação". Usando <code>FormView</code>, você ainda precisa criar seu <code>Form</code>, mas não precisa implementar todos os padrões de manipulação de formulário. Em vez disso, você tem apenas que fornecer uma implementação da função que será chamada assim que o envio for válido.</p>
+</div>
+
+<p>Nessa seção vamos usar <em>views</em> genericas de edição para criar páginas para adicionar funcionalidades para criar, editar e excluir registros de <code>Author</code> da nossa biblioteca — fornecendo efetivamente uma reimplementação básica de parte do site <em>Admin</em> (isso poderá ser útil se você precisa oferecer funcionalidades de administrador de uma maneira mais flexível que possa ser fornecida pelo dite <em>Admin</em>).</p>
+
+<h3 id="Views"><em>Views</em></h3>
+
+<p>Abra o arquivo das <em>views</em> (<strong>locallibrary/catalog/views.py</strong>) e acrescente o seguinte bloco de código na parte inferior:</p>
+
+<pre class="brush: python">from django.views.generic.edit import CreateView, UpdateView, DeleteView
+from django.urls import reverse_lazy
+
+from catalog.models import Author
+
+class AuthorCreate(CreateView):
+ model = Author
+ fields = '__all__'
+ initial = {'date_of_death': '05/01/2018'}
+
+class AuthorUpdate(UpdateView):
+ model = Author
+ fields = ['first_name', 'last_name', 'date_of_birth', 'date_of_death']
+
+class AuthorDelete(DeleteView):
+ model = Author
+ success_url = reverse_lazy('authors')</pre>
+
+<p>Como você pode ver, para criar, atualizar e excluir as <em>views</em>, você precisa derivar de <code>CreateView</code>, <code>UpdateView</code>, e <code>DeleteView</code> (respectivamente) e então definir o modelo associado.</p>
+
+<p>Para os casos "criar" e "atualizar" você também precisa especificar os campos para mostrar no formulário (usando a mesma sintaxe que para <code>ModelForm</code>). Nesse caso, nós mostramos ambas as sintaxes para mostrar todos (<em>"all"</em>) campos e como você pode listar eles individualmente. Você também pode especificar valores iniciais para cada campo usando um dicionário com pares nome_campo/valor (aqui, arbitrariamente, definimos a data de morte para fins de demonstração — talvez você queira remover isso!). Por padrão, essas <em>views</em> irão redirecionar, se houver sucesso, para uma página mostrando o item do modelo recentemente criado/editado, que no nosso caso será a página de visualização de detalhes do autor que criamos em um tutorial anterior. Você pode especificar ums local de redirecionamento alternativo, declarando explicitamente o parâmetro <code>success_url</code> (como feito na classe <code>AuthorDelete</code>).</p>
+
+<p>A classe <code>AuthorDelete</code>  não precisa mostrar nenhum dos campos, então eles não precisam ser especificados. No entanto, você precisa especificar a  <code>success_url</code>, porque  não há um valor padrão óbvio para o Django usar. Nesse caso, usamos a função <code><a href="https://docs.djangoproject.com/en/2.1/ref/urlresolvers/#reverse-lazy">reverse_lazy()</a></code> para redirecioanr para nossa lista de autores depois que um autor é excluido — <code>reverse_lazy()</code> é uma versão executada "preguiçosamente" de <code>reverse()</code>, usada aqui porque estamos fornecendo uma URL para um atributo baseado em classe de <em>view</em>.</p>
+
+<h3 id="Templates"><em>Templates</em></h3>
+
+<p>As <em>views</em> "<em>create</em>" e "<em>update</em>"  usam o mesmo <em>template</em> por padrão, que serão nomeadas seguindo o modelo: <em>model_name</em><strong>_form.html</strong> (você pode mudar o sufixo para algo diferente de <strong>_form</strong> usando o campo <code>template_name_suffix</code> em sua <em>view</em>, ex. <code>template_name_suffix = '_other_suffix'</code>)</p>
+
+<p>Crie o arquivo de <em>template  </em><strong>locallibrary/catalog/templates/catalog/author_form.html</strong> e copie o texto abaixo.</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;form action="" method="post"&gt;
+ {% csrf_token %}
+ &lt;table&gt;
+ \{{ form.as_table }}
+ &lt;/table&gt;
+ &lt;input type="submit" value="Submit"&gt;
+ &lt;/form&gt;
+{% endblock %}</pre>
+
+<p>Isso é semelhante aos nossos formulários anteriores e renderiza os campos usando uma tabela. Note também como novamente declaramos o <code>{% csrf_token %}</code> para garantir que nossos formulários são resistentes a ataques CSRF.</p>
+
+<p>A <em>view</em> "delete" espera encontrar um <em>template</em> nomeado com o formato  <em>model_name</em><strong>_confirm_delete.html</strong> (novamente, você pode mudar o sufixo usando <code>template_name_suffix</code> em sua <em>view</em>). Crie o arquivo de <em>template</em> <strong>locallibrary/catalog/templates/catalog/author_confirm_delete</strong><strong>.html</strong> e copie o texto abaixo.</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+
+{% block content %}
+
+&lt;h1&gt;Delete Author&lt;/h1&gt;
+
+&lt;p&gt;Are you sure you want to delete the author: \{{ author }}?&lt;/p&gt;
+
+&lt;form action="" method="POST"&gt;
+ {% csrf_token %}
+ &lt;input type="submit" value="Yes, delete."&gt;
+&lt;/form&gt;
+
+{% endblock %}
+</pre>
+
+<h3 id="URL_configurations">URL configurations</h3>
+
+<p>Abra seu arquivo de configuração de URL (<strong>locallibrary/catalog/urls.py</strong>)  e adicione a seguinte configuração no final do arquivo:</p>
+
+<pre class="brush: python">urlpatterns += [
+    path('author/create/', views.AuthorCreate.as_view(), name='author_create'),
+    path('author/&lt;int:pk&gt;/update/', views.AuthorUpdate.as_view(), name='author_update'),
+    path('author/&lt;int:pk&gt;/delete/', views.AuthorDelete.as_view(), name='author_delete'),
+]</pre>
+
+<p>Não há nada particularmente novo aqui! Você pode ver que  as <em>views</em> são classes, e portanto devem ser chamadas via <code>.as_view()</code>, e você deve poder reconhecer os padrões URL em cada caso. Devemos usar <code>pk</code> como o nome para nosso valor capturado de chave primária (<em>primary key</em>), como esse é o nome do parâmetro esperado pelas classes <em>view</em>.</p>
+
+<p>As páginas de criação, atualização e remoção de autor agora estão prontas para teste (neste caso, não nos incomodaremos em conectá-las a barra lateral do site, embora você possa fazer se desejar).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Usuários observadores devem ter notado que não fizemos nada para previnir que usuários não autorizadosde acessem as páginas! Deixamos isso como um exercício para você (dica: você pode usar  <code>PermissionRequiredMixin</code> e criar uma nova permissão ou reutilizar nossa permissão <code>can_mark_returned</code>).</p>
+</div>
+
+<h3 id="Testando_a_página_2">Testando a página</h3>
+
+<p>Primeiro, efetue login no site com uma conta que possua as permissões que você decidiu que são necessárias para acessar a página de edição de autor.</p>
+
+<p>Então navegue para a página de criação de autor: <a href="http://127.0.0.1:8000/catalog/author/create/">http://127.0.0.1:8000/catalog/author/create/</a>, que deve parecer como a captura de tela abaixo.</p>
+
+<p><img alt="Form Example: Create Author" src="https://mdn.mozillademos.org/files/14223/forms_example_create_author.png" style="border-style: solid; border-width: 1px; display: block; height: 184px; margin: 0px auto; width: 645px;"></p>
+
+<p>Entre com valores para os campos e então pressione <strong>Submit</strong> para dalvar o registro de autor. Você agora deve ser direcionado para uma visualização detalhada para o seu novo autor, com uma URL de algo como <em>http://127.0.0.1:8000/catalog/author/10</em>.</p>
+
+<p>Você pode testar edição de registros enexando <em>/update/</em> ao final da URL da página de detalhe (ex. <em>http://127.0.0.1:8000/catalog/author/10/update/</em>) — não mostramos uma captura de tela, porque se parace com a página de criação</p>
+
+<p>Finalmente, podemos excluir a página anexando <em>delete</em> ao final da URL da visualização detalhada do autor  (ex. <em>http://127.0.0.1:8000/catalog/author/10/delete/</em>). Django deve exibir a página de exclusão mostrada abaixo. Pressione <strong>Yes, delete.</strong> para remover o registro e ser levado para a lista de todos os autores.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14221/forms_example_delete_author.png" style="border-style: solid; border-width: 1px; display: block; height: 194px; margin: 0px auto; width: 561px;"></p>
+
+<h2 id="Desafie-se">Desafie-se</h2>
+
+<p>Crie alguns <em>forms</em> para criar, editar e excluir registros de <code>Book</code>. Você pode utilizar exatamente a mesma estrutura que a de  <code>Authors</code>. Se seu <em>template</em> <strong>book_form.html</strong> é apenas uma cópia renomeada de   <strong>author_form.html</strong> , então a nova página "criar livro" será semelhante a captura de tela abaixo:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14225/forms_example_create_book.png" style="border-style: solid; border-width: 1px; display: block; height: 521px; margin: 0px auto; width: 595px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Criar e manipular formulários pode ser um processo complicado! Django torna muito mais fácil fornecendo mecanismos programáticos para declarar, renderizar e validar formulários. Além disso, Django fornece <em>views</em> genéricas de edição de formulário, isso pode fazes quase todo trabalho para definir páginas que podem criar, editar e excluir registros associados com uma única instância de <em>model.</em></p>
+
+<p>Há muito mais que pode ser feito com formulários (confira abaixo nossa lista Veja também), mas agora você deve entender como adicionar formulários básicos e o código de manipulação de formulários para seus próprios websites.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/forms/">Trabalhando com formulários</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial04/#write-a-simple-form">Escrevendo seu primeiro <em>app</em> Django, parte 4 &gt; Escrevendo um formulário simples</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/api/">A API <em>Forms</em></a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/">Form fields</a> (Django docs) </li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/validation/">Formulários e validação de campos</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-editing/">Manipulação de formulários com <em>views</em> baseadas em classe</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/">Criando formulários com <em>models</em></a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/">Views genéricas de edição</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: </a><a rel="nofollow" title="A página ainda não foi criada.">Website de uma Biblioteca Local</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Parte 2: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Criando a base do website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Models">Django Parte 3: Usando <em>models</em></a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Parte 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Parte 6: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Generic_views">Lista genérica e <em>detail views</em></a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Parte 7: </a><a rel="nofollow" title="A página ainda não foi criada.">Framework de Sessões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Parte 8: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Authentication">Autenticação de Usuário e permissões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Parte 9: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Forms">Trabalhando com formulários</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Parte 10: </a><a rel="nofollow" title="A página ainda não foi criada.">Testando uma aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Parte 11: </a><a rel="nofollow" title="A página ainda não foi criada.">Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/generic_views/index.html b/files/pt-br/learn/server-side/django/generic_views/index.html
new file mode 100644
index 0000000000..f5a176b192
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/generic_views/index.html
@@ -0,0 +1,617 @@
+---
+title: 'Tutorial Django Parte 6: Lista genérica e detail views'
+slug: Learn/Server-side/Django/Generic_views
+translation_of: Learn/Server-side/Django/Generic_views
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Este tutorial estende nosso website <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, adicionando páginas de lista e detalhes para livros e autores. Aqui, aprenderemos sobre visualizações genéricas baseadas em classe e mostraremos como elas podem reduzir a quantidade de código que você precisa escrever para casos de uso comuns. Também abordaremos o tratamento de URLs em mais detalhes, mostrando como executar a correspondência básica de padrões.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Conclua todos os tópicos do tutorial anterior, incluindo <a href="/pt-br/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Para entender onde e como usar modos de exibição genéricos baseados em classe e como extrair padrões de URLs e passar as informações para modos de exibição.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_global">Visão global</h2>
+
+<p>Neste tutorial, vamos concluir a primeira versão do website <a href="https://developer.mozilla.org/pt-br/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a> adicionando páginas de lista e detalhes de livros e autores (ou, para ser mais preciso, mostraremos como implementar as páginas do livro e você mesmo irá criar as páginas dos autores!)</p>
+
+<p>O processo é semelhante à criação da página index, que mostramos no tutorial anterior. Ainda precisamos criar mapas de URL, views e templates. A principal diferença é que, para as páginas de detalhes, teremos o desafio adicional de extrair informações de padrões no URL e passá-las para a visualização. Para essas páginas, demonstraremos um tipo de exibição completamente diferente: lista genérica baseada em classe e exibições detalhadas. Isso pode reduzir significativamente a quantidade de código de visualização necessária, facilitando a gravação e a manutenção.</p>
+
+<p>A parte final do tutorial demonstrará como paginar seus dados ao usar visualizações de lista genéricas baseadas em classe.</p>
+
+<h2 id="Book_list_page">Book list page</h2>
+
+<p>A página da lista de livros exibirá uma lista de todos os registros de livros disponíveis na página, acessados usando o URL: <code>catalog/books/</code>. A página exibirá um título e um autor para cada registro, com o título sendo um hiperlink para a página de detalhes do livro associada. A página terá a mesma estrutura e navegação que todas as outras páginas do site e, portanto, podemos estender o modelo base (<strong>base_generic.html</strong>) que criamos no tutorial anterior.</p>
+
+<h3 id="URL_mapping">URL mapping</h3>
+
+<p>Abra <strong>/catalog/urls.py</strong> e copie na linha mostrada em negrito abaixo. Quanto à página index, a função <code>path()</code> define um padrão para corresponder ao URL (<strong>'books/'</strong>), a função view que será chamado se o URL corresponder (<code>views.BookListView.as_view()</code>), e um nome para esse mapeamento específico.</p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+ path('', views.index, name='index'),
+<strong>  </strong>path<strong>('books/', views.BookListView.as_view(), name='books'),</strong>
+]</pre>
+
+<p>Conforme discutido no tutorial anterior, o URL já deve ter correspondencia <code>/catalog</code>, então a visualização será realmente chamada para o URL: <code>/catalog/books/</code>.</p>
+
+<p>A função view tem um formato diferente do que antes - é porque essa view será realmente implementada como uma classe. Herdaremos de uma função view genérica existente que já faz a maior parte do que queremos que essa função view faça, em vez de escrever a nossa a partir do zero.</p>
+
+<p>Para as class-based views do Django, acessamos uma função de visualização apropriada chamando o método de classe <code>as_view()</code>. Isso faz todo o trabalho de criar uma instância da classe e garantir que os métodos do manipulador certo sejam chamados para solicitações HTTP recebidas.</p>
+
+<h3 id="View_class-based">View (class-based)</h3>
+
+<p>Poderíamos escrever com facilidade a view da lista de livros como uma função regular (assim como a view index anterior), que consultaria todos os livros no banco de dados e depois chamaria <code>render()</code> para passar a lista para um modelo especificado. No entanto, usaremos uma view de lista genérica class-based (<code>ListView</code>) — uma classe que herda de uma view existente. Como a view genérica já implementa a maioria das funcionalidades necessárias e segue as práticas recomendadas do Django, poderemos criar uma exibição de lista mais robusta com menos código, menos repetições e, finalmente, menos manutenção.</p>
+
+<p>Abra <strong>catalog/views.py</strong>, e copie o seguinte código na parte inferior do arquivo:</p>
+
+<pre class="brush: python notranslate">from django.views import generic
+
+class BookListView(generic.ListView):
+ model = Book</pre>
+
+<p>É isso aí! A view genérica consultará o banco de dados para obter todos os registros para o modelo especificado (<code>Book</code>) em seguida, renderize um template localizado em <strong>/locallibrary/catalog/templates/catalog/book_list.html</strong> (que criaremos abaixo). Dentro do template, você pode acessar a lista de livros com a variável de template denominada <code>object_list</code> OU <code>book_list</code> (i.e. genericamente "<code><em>the_model_name</em>_list</code>").</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Esse caminho estranho para a localização do template não é um erro de impressão - as visualizações genéricas procuram modelos em <code>/<em>application_name</em>/<em>the_model_name</em>_list.html</code> (<code>catalog/book_list.html</code> nesse caso) dentro do aplicativo <code>/<em>application_name</em>/templates/</code> diretório (<code>/catalog/templates/)</code>.</p>
+</div>
+
+<p>Você pode adicionar atributos para alterar o comportamento padrão acima. Por exemplo, você pode especificar outro arquivo do template se precisar ter várias visualizações que usem esse mesmo modelo ou se desejar usar um nome de variável de template diferente se <code>book_list</code> não é intuitivo para o seu caso de uso de template específico. Possivelmente, a variação mais útil é alterar/filtrar o subconjunto de resultados retornados - portanto, em vez de listar todos os livros, você pode listar os cinco principais livros que foram lidos por outros usuários.</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+ context_object_name = 'my_book_list' # your own name for the list as a template variable
+ queryset = Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
+ template_name = 'books/my_arbitrary_template_name_list.html' # Specify your own template name/location</pre>
+
+<h4 id="Substituindo_métodos_em_class-based_views">Substituindo métodos em class-based views</h4>
+
+<p>Embora não precisemos fazer isso aqui, você também pode substituir alguns dos métodos da classe.</p>
+
+<p>Por exemplo, podemos substituir o método <code>get_queryset()</code> para alterar a lista de registros retornados. Isso é mais flexível do que apenas definir o atributo <code>queryset</code> como fizemos no fragmento de código anterior (embora não haja nenhum benefício real neste caso):</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+
+    def get_queryset(self):
+        return Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
+</pre>
+
+<p>Também podemos substituir <code>get_context_data()</code> para passar variáveis de contexto adicionais para o template (por exemplo, a lista de livros é passada por padrão). O fragmento abaixo mostra como adicionar uma variável chamada "<code>some_data</code>" para o contexto (estaria disponível como uma variável de template).</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+
+    def get_context_data(self, **kwargs):
+        # Call the base implementation first to get the context
+        context = super(BookListView, self).get_context_data(**kwargs)
+        # Create any data and add it to the context
+        context['some_data'] = 'This is just some data'
+        return context</pre>
+
+<p>Ao fazer isso, é importante seguir o padrão usado acima:</p>
+
+<ul>
+ <li>Primeiro obtenha o contexto existente da nossa superclasse.</li>
+ <li>Em seguida, adicione as novas informações de contexto.</li>
+ <li>Em seguida, retorne o novo contexto (atualizado).</li>
+</ul>
+
+<div class="note">
+<p><strong>Nota</strong>: Confira <a href="https://docs.djangoproject.com/pt-br/2.1/topics/class-based-views/generic-display/">Built-in class-based generic views</a> (Django docs) para muitos mais exemplos do que você pode fazer.</p>
+</div>
+
+<h3 id="Criando_o_template_List_View">Criando o template List View</h3>
+
+<p>Crie o arquivo HTML <strong>/locallibrary/catalog/templates/catalog/book_list.html</strong> e copie o texto abaixo. Como discutido acima, este é o arquivo de template padrão esperado pela list view genérica da class-based view (para um modelo chamado <code>Book</code> em um aplicativo chamado <code>catalog</code>).</p>
+
+<p>Os templates para visualizações genéricas são como qualquer outro template (<em>embora</em>, é claro, o contexto/informações passadas para o template possam ser diferentes). Assim como em nosso template <em>index</em>, estendemos nosso template base na primeira linha e substituímos o bloco denominado <code>content</code>.</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Book List&lt;/h1&gt;
+  <strong>{% if book_list %}</strong>
+  &lt;ul&gt;
+  {% for book in book_list %}
+      &lt;li&gt;
+        &lt;a href="\{{ book.get_absolute_url }}"&gt;\{{ book.title }}&lt;/a&gt; (\{{book.author}})
+      &lt;/li&gt;
+  {% endfor %}
+  &lt;/ul&gt;
+  <strong>{% else %}</strong>
+  &lt;p&gt;There are no books in the library.&lt;/p&gt;
+  <strong>{% endif %} </strong>
+{% endblock %}</pre>
+
+<p>A view passa o contexto (lista de livros), por padrão, um <code>object_list</code> e <code>book_list</code> aliases; qualquer um funcionará.</p>
+
+<h4 id="Execução_conditional">Execução conditional</h4>
+
+<p>Nós usamos o <code><a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#if">if</a></code>, <code>else</code>, e <code>endif</code> template tags para verificar se o <code>book_list</code> foi definido e não está vazio. E se <code>book_list</code> está vazio, então a cláusula <code>else</code> exibe o  texto explicando que não há livros para listar. E se <code>book_list</code> não estiver vazio, percorreremos a lista de livros.</p>
+
+<pre class="brush: html notranslate"><strong>{% if book_list %}</strong>
+ &lt;!-- code here to list the books --&gt;
+<strong>{% else %}</strong>
+ &lt;p&gt;There are no books in the library.&lt;/p&gt;
+<strong>{% endif %}</strong>
+</pre>
+
+<p>A condição acima verifica apenas um caso, mas você pode testar em condições adicionais usando a template tag <code>elif</code> (e.g. <code>{% elif var2 %}</code>). Para obter mais informações sobre operadores condicionais, consulte: <a href="https://docs.djangoproject.com/pt-br/2.1/ref/templates/builtins/#if">if</a>, <a href="https://docs.djangoproject.com/pt-br/2.1/ref/templates/builtins/#ifequal-and-ifnotequal">ifequal/ifnotequal</a>, e <a href="https://docs.djangoproject.com/pt-br/2.1/ref/templates/builtins/#ifchanged">ifchanged</a> em <a href="https://docs.djangoproject.com/pt-br/2.1/ref/templates/builtins">Built-in template tags and filters</a> (Django Docs).</p>
+
+<h4 id="For_loops">For loops</h4>
+
+<p>O template usa as template tags <a href="https://docs.djangoproject.com/pt-br/2.1/ref/templates/builtins/#for">for</a> e <code>endfor</code> para percorrer a lista de livros, como mostrado abaixo. Cada iteração preenche a variável de template <code>book</code> com informações para o item da lista atual.</p>
+
+<pre class="brush: html notranslate">{% for <strong>book</strong> in book_list %}
+ &lt;li&gt; &lt;!-- code here get information from each <strong>book</strong> item --&gt; &lt;/li&gt;
+{% endfor %}
+</pre>
+
+<p>Embora não seja usado aqui, dentro do loop, o Django também criará outras variáveis que você pode usar para rastrear a iteração. Por exemplo, você pode testar a variável  <code>forloop.last</code> para executar o processamento condicional na última vez em que o loop é executado.</p>
+
+<h4 id="Acessando_variáveis">Acessando variáveis</h4>
+
+<p>O código dentro do loop cria um item de lista para cada livro que mostra o título (como um link para a exibição de detalhes ainda a ser criada) e o autor.</p>
+
+<pre class="brush: html notranslate">&lt;a href="\{{ book.get_absolute_url }}"&gt;\{{ book.title }}&lt;/a&gt; (\{{book.author}})
+</pre>
+
+<p>Acessamos os <em>campos </em>do registro de livro associado usando a "notação de ponto" (e.g. <code>book.title</code> e <code>book.author</code>), onde o texto após o item <code>book</code> é o nome do campo (conforme definido no modelo).</p>
+
+<p>Também podemos chamar <em>funções </em>no modelo de dentro do nosso template - nesse caso, chamamos <code>Book.get_absolute_url()</code> para obter um URL que você pode usar para exibir o registro de detalhe associado. Isso funciona desde que a função não tenha argumentos (não há como passar argumentos!)</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Temos que ter um pouco de cuidado com os "efeitos colaterais" ao chamar funções em templates. Aqui apenas exibimos um URL, mas uma função pode fazer praticamente qualquer coisa - não queremos excluir nosso banco de dados (por exemplo) apenas renderizando nosso template!</p>
+</div>
+
+<h4 id="Atualize_o_template_base">Atualize o template base</h4>
+
+<p>Abra o template base (<strong>/locallibrary/catalog/templates/<em>base_generic.html</em></strong>) e insira <strong>{% url 'books' %} </strong>no link da URL para <strong>All books</strong>,como mostrado abaixo. Isso habilitará o link em todas as páginas (podemos colocá-lo em prática agora que criamos o mapeador de URL "books").</p>
+
+<pre class="brush: python notranslate">&lt;li&gt;&lt;a href="{% url 'index' %}"&gt;Home&lt;/a&gt;&lt;/li&gt;
+<strong>&lt;li&gt;&lt;a href="{% url 'books' %}"&gt;All books&lt;/a&gt;&lt;/li&gt;</strong>
+&lt;li&gt;&lt;a href=""&gt;All authors&lt;/a&gt;&lt;/li&gt;</pre>
+
+<h3 id="Com_o_que_se_parece">Com o que se parece?</h3>
+
+<p>Ainda não será possível criar a lista de livros, porque ainda falta uma dependência - o mapa de URL para as páginas de detalhes do livro, necessário para criar hiperlinks para livros individuais. Mostraremos as visualizações de lista e de detalhes após a próxima seção.</p>
+
+<h2 id="Pagina_Book_detail">Pagina Book detail</h2>
+
+<p>A página book detail exibirá informações sobre um livro específico, acessado usando o URL <code>catalog/book/<em>&lt;id&gt;</em></code> (onde <code><em>&lt;id&gt;</em></code> é a chave primária do livro). Além dos campos no model <code>Book</code> (author, summary, ISBN, language, e genre), também listaremos os detalhes das cópias disponíveis (<code>BookInstances</code>) incluindo o status, data prevista de retorno, impressão e ID. Isso permitirá que nossos leitores não apenas saibam sobre o livro, mas também confirmem se/quando ele está disponível.</p>
+
+<h3 id="URL_mapping_2">URL mapping</h3>
+
+<p>Abra <strong>/catalog/urls.py</strong> e adicione a URL '<strong>book-detail</strong>' mostrado em negrito abaixo. Esta função <code>path()</code> define um padrão, exibição de detalhes genérica associada à classe associada e um nome.</p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+ path('', views.index, name='index'),
+    path('books/', views.BookListView.as_view(), name='books'),
+<strong>  path('book/&lt;int:pk&gt;', views.BookDetailView.as_view(), name='book-detail'),</strong>
+]</pre>
+
+<p>Para o path <em>book-detail</em> o padrão de URL usa uma sintaxe especial para capturar o ID específico do livro que queremos ver. A sintaxe é muito simples: colchetes angulares definem a parte da URL a ser capturada, incluindo o nome da variável que a view pode usar para acessar os dados capturados. Por exemplo, <strong>&lt;something&gt;</strong> , capturará o padrão marcado e passará o valor para a visualização como uma variável "alguma coisa". Opcionalmente, você pode preceder o nome da variável com um <a href="https://docs.djangoproject.com/pt-br/2.1/topics/http/urls/#path-converters">converter specification</a> que define o tipo de dados (int, str, slug, uuid, path).</p>
+
+<p>Neste caso, usamos <code>'&lt;int:pk&gt;'</code><strong> </strong>para capturar o ID do livro, que deve ser uma sequência especialmente formatada e passá-la para a view como um parâmetro chamado <code>pk</code> (abreviatura de primary key). Esta é a id que está sendo usado para armazenar o livro exclusivamente no banco de dados, conforme definido no Book Model.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Como discutido anteriormente, nosso URL correspondente é realmente <code>catalog/book/&lt;digits&gt;</code> (porque estamos no aplicativo de <strong>catalog</strong>, <code>/catalog/</code> é assumido).</p>
+</div>
+
+<div class="warning">
+<p><strong>Importante</strong>: A view de detalhes genérica class-based <em>espera </em>receber um parâmetro chamado <strong>pk</strong>. Se você estiver escrevendo sua própria função view, poderá usar o nome de qualquer parâmetro que desejar, ou mesmo transmitir as informações em um argumento sem nome.</p>
+</div>
+
+<h4 id="Correspondência_avançada_de_caminhosiniciador_de_expressão_regular">Correspondência avançada de caminhos/iniciador de expressão regular</h4>
+
+<div class="note">
+<p><strong>Nota</strong>: Você não precisará desta seção para concluir o tutorial! Nós fornecemos isso porque conhecer essa opção provavelmente será útil no seu futuro centrado no Django.</p>
+</div>
+
+<p>The pattern matching provided by <code>path()</code> is simple and useful for the (very common) cases where you just want to capture <em>any</em> string or integer. If you need more refined filtering (for example, to filter only strings that have a certain number of characters) then you can use the <a href="https://docs.djangoproject.com/en/2.1/ref/urls/#django.urls.re_path">re_path()</a> method.</p>
+
+<p>This method is used just like <code>path()</code> except that it allows you to specify a pattern using a <a href="https://docs.python.org/3/library/re.html">Regular expression</a>. For example, the previous path could have been written as shown below:</p>
+
+<pre class="brush: python notranslate"><strong>re_path(r'^book/(?P&lt;pk&gt;\d+)$', views.BookDetailView.as_view(), name='book-detail'),</strong>
+</pre>
+
+<p><em>Regular expressions</em> are an incredibly powerful pattern mapping tool. They are, frankly, quite unintuitive and scary for beginners. Below is a very short primer!</p>
+
+<p>The first thing to know is that regular expressions should usually be declared using the raw string literal syntax (i.e. they are enclosed as shown: <strong>r'&lt;your regular expression text goes here&gt;'</strong>).</p>
+
+<p>The main parts of the syntax you will need to know for declaring the pattern matches are:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Symbol</th>
+ <th scope="col">Meaning</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>^</td>
+ <td>Match the beginning of the text</td>
+ </tr>
+ <tr>
+ <td>$</td>
+ <td>Match the end of the text</td>
+ </tr>
+ <tr>
+ <td>\d</td>
+ <td>Match a digit (0, 1, 2, ... 9)</td>
+ </tr>
+ <tr>
+ <td>\w</td>
+ <td>Match a word character, e.g. any upper- or lower-case character in the alphabet, digit or the underscore character (_)</td>
+ </tr>
+ <tr>
+ <td>+</td>
+ <td>Match one or more of the preceding character. For example, to match one or more digits you would use <code>\d+</code>. To match one or more "a" characters, you could use <code>a+</code></td>
+ </tr>
+ <tr>
+ <td>*</td>
+ <td>Match zero or more of the preceding character. For example, to match nothing or a word you could use <code>\w*</code></td>
+ </tr>
+ <tr>
+ <td>( )</td>
+ <td>Capture the part of the pattern inside the brackets. Any captured values will be passed to the view as unnamed parameters (if multiple patterns are captured, the associated parameters will be supplied in the order that the captures were declared).</td>
+ </tr>
+ <tr>
+ <td>(?P&lt;<em>name</em>&gt;...)</td>
+ <td>Capture the pattern (indicated by ...) as a named variable (in this case "name"). The captured values are passed to the view with the name specified. Your view must therefore declare an argument with the same name!</td>
+ </tr>
+ <tr>
+ <td>[  ]</td>
+ <td>Match against one character in the set. For example, [abc] will match on 'a' or 'b' or 'c'. [-\w] will match on the '-' character or any word character.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Most other characters can be taken literally!</p>
+
+<p>Let's consider a few real examples of patterns:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Pattern</th>
+ <th scope="col">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>r'^book/(?P&lt;pk&gt;\d+)$'</strong></td>
+ <td>
+ <p>This is the RE used in our URL mapper. It matches a string that has <code>book/</code> at the start of the line (<strong>^book/</strong>), then has one or more digits (<code>\d+</code>), and then ends (with no non-digit characters before the end of line marker).</p>
+
+ <p>It also captures all the digits <strong>(?P&lt;pk&gt;\d+)</strong> and passes them to the view in a parameter named 'pk'. <strong>The captured values are always passed as a string!</strong></p>
+
+ <p>For example, this would match <code>book/1234</code> , and send a variable <code>pk='1234'</code> to the view.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>r'^book/(\d+)$'</strong></td>
+ <td>This matches the same URLs as the preceding case. The captured information would be sent as an unnamed argument to the view.</td>
+ </tr>
+ <tr>
+ <td><strong>r'^book/(?P&lt;stub&gt;[-\w]+)$'</strong></td>
+ <td>
+ <p>This matches a string that has <code>book/</code> at the start of the line (<strong>^book/</strong>), then has one or more characters that are <em>either</em> a '-' or a word character (<strong>[-\w]+</strong>), and then ends. It also captures this set of characters and passes them to the view in a parameter named 'stub'.</p>
+
+ <p>This is a fairly typical pattern for a "stub". Stubs are URL-friendly word-based primary keys for data. You might use a stub if you wanted your book URL to be more informative. For example <code>/catalog/book/the-secret-garden</code> rather than <code>/catalog/book/33</code>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>You can capture multiple patterns in the one match, and hence encode lots of different information in a URL.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Como desafio, considere como você pode codificar um URL para listar todos os livros lançados em um determinado ano, mês, dia e o RE que poderia ser usado para correspondê-lo.</p>
+</div>
+
+<h4 id="Passando_opções_adicionais_em_seus_mapas_de_URL">Passando opções adicionais em seus mapas de URL</h4>
+
+<p>Um recurso que não usamos aqui, mas que você pode achar valioso, é que você pode declarar e passar <a href="https://docs.djangoproject.com/pt-br/2.1/topics/http/urls/#views-extra-options">opções adicionais</a> para a view. As opções são declaradas como um dicionário que você passa como o terceiro argumento sem nome para a função <code>path()</code>. Essa abordagem pode ser útil se você desejar usar a mesma visualização para vários recursos e transmitir dados para configurar seu comportamento em cada caso (abaixo, fornecemos um modelo diferente em cada caso).</p>
+
+<pre class="brush: python notranslate">path('url/', views.my_reused_view, <strong>{'my_template_name': 'some_path'}</strong>, name='aurl'),
+path('anotherurl/', views.my_reused_view, <strong>{'my_template_name': 'another_path'}</strong>, name='anotherurl'),
+</pre>
+
+<div class="note">
+<p><strong>Nota:</strong> As opções extras e os padrões capturados nomeados são passados para a view como argumentos <em>nomeados</em>. Se você usar o <strong>mesmo nome</strong> para um padrão capturado e uma opção extra, somente o valor do padrão capturado será enviado para a visualização (o valor especificado na opção adicional será descartado).</p>
+</div>
+
+<h3 id="View_class-based_2">View (class-based)</h3>
+
+<p>Abra <strong>catalog/views.py</strong>, e copie o seguinte código na parte inferior do arquivo:</p>
+
+<pre class="brush: python notranslate">class BookDetailView(generic.DetailView):
+    model = Book</pre>
+
+<p>É isso aí! Tudo o que você precisa fazer agora é criar um modelo chamado <strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>, e a visualização passará as informações do banco de dados para o registro <code>Book</code> extraído pelo mapeador de URL. Dentro do modelo, você pode acessar a lista de livros com a variável de modelo denominada <code>object</code> ou <code>book</code> (i.e. genericamente "<code><em>the_model_name</em></code>").</p>
+
+<p>Se necessário, você pode alterar o template usado e o nome do objeto de contexto usado para referenciar o livro no template. Você também pode substituir métodos para, por exemplo, adicionar informações adicionais ao contexto.</p>
+
+<h4 id="O_que_acontece_se_o_registro_não_existir">O que acontece se o registro não existir?</h4>
+
+<p>Se um registro solicitado não existir, a view de detalhes genérica class-based levantará uma exceção <code>Http404</code> para você automaticamente — em produção, isso exibirá automaticamente uma página apropriada de "resource not found", que você pode personalizar se desejar.</p>
+
+<p>Apenas para lhe dar uma idéia de como isso funciona, o fragmento de código abaixo demonstra como você implementaria a exibição baseada em classe como uma função se você não estivesse usando a view de detalhe genérica class-based.</p>
+
+<pre class="brush: python notranslate">def book_detail_view(request, primary_key):
+ try:
+ book = Book.objects.get(pk=primary_key)
+ except Book.DoesNotExist:
+ raise Http404('Book does not exist')
+
+ return render(request, 'catalog/book_detail.html', context={'book': book})
+</pre>
+
+<p>A view tenta primeiro obter o registro de livro específico do modelo. Se isso falhar, a view deve gerar uma exceção <code>Http404</code> para indicar que o livro "não foi encontrado". A etapa final é, como sempre, chamar <code>render()</code> com o nome do template e os dados do livro no parâmetro <code>context</code> (como um dicionário).</p>
+
+<p>Como alternativa, podemos usar a função <code>get_object_or_404()</code> como um atalho para levantar uma exceção <code>Http404</code> se o registro não for encontrado.</p>
+
+<pre class="brush: python notranslate">from django.shortcuts import get_object_or_404
+
+def book_detail_view(request, primary_key):
+  book = get_object_or_404(Book, pk=primary_key)
+ return render(request, 'catalog/book_detail.html', context={'book': book})</pre>
+
+<h3 id="Criando_o_template_Detail_View">Criando o template Detail View</h3>
+
+<p>Crie o arquivo HTML <strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong> e forneça o conteúdo abaixo. Conforme discutido acima, este é o nome do arquivo de template padrão esperado pela view de <em>detalhes </em>genérica class-based (para um modelo chamado <code>Book</code> no aplicativo chamado <code>catalog</code>).</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Title: \{{ book.title }}&lt;/h1&gt;
+
+ &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; &lt;a href=""&gt;\{{ book.author }}&lt;/a&gt;&lt;/p&gt; &lt;!-- author detail link not yet defined --&gt;
+ &lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; \{{ book.summary }}&lt;/p&gt;
+ &lt;p&gt;&lt;strong&gt;ISBN:&lt;/strong&gt; \{{ book.isbn }}&lt;/p&gt;
+ &lt;p&gt;&lt;strong&gt;Language:&lt;/strong&gt; \{{ book.language }}&lt;/p&gt;
+ &lt;p&gt;&lt;strong&gt;Genre:&lt;/strong&gt; {% for genre in book.genre.all %} \{{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}&lt;/p&gt;
+
+ &lt;div style="margin-left:20px;margin-top:20px"&gt;
+ &lt;h4&gt;Copies&lt;/h4&gt;
+
+ {% for copy in book.bookinstance_set.all %}
+ &lt;hr&gt;
+ &lt;p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}"&gt;\{{ copy.get_status_display }}&lt;/p&gt;
+ {% if copy.status != 'a' %}
+ &lt;p&gt;&lt;strong&gt;Due to be returned:&lt;/strong&gt; \{{copy.due_back}}&lt;/p&gt;
+ {% endif %}
+ &lt;p&gt;&lt;strong&gt;Imprint:&lt;/strong&gt; \{{copy.imprint}}&lt;/p&gt;
+ &lt;p class="text-muted"&gt;&lt;strong&gt;Id:&lt;/strong&gt; \{{copy.id}}&lt;/p&gt;
+ {% endfor %}
+ &lt;/div&gt;
+{% endblock %}</pre>
+
+<ul>
+</ul>
+
+<div class="note">
+<p>O link do autor no template acima tem um URL vazio porque ainda não criamos uma página de detalhes do autor. Uma vez que isso exista, você deve atualizar o URL assim:</p>
+
+<pre class="notranslate">&lt;a href="<strong>{% url 'author-detail' book.author.pk %}</strong>"&gt;\{{ book.author }}&lt;/a&gt;
+</pre>
+</div>
+
+<p>Embora um pouco maior, quase tudo neste template foi descrito anteriormente:</p>
+
+<ul>
+ <li>Estendemos nosso modelo básico e substituímos o bloco "content".</li>
+ <li>Usamos o processamento condicional para determinar se deve ou não exibir conteúdo específico.</li>
+ <li>Usamos <code>for</code> loops para percorrer as listas de objetos.</li>
+ <li>Acessamos os campos de contexto usando a notação de ponto (porque usamos a exibição genérica detalhada, o contexto é chamado <code>book</code>; também poderíamos usar "<code>object</code>")</li>
+</ul>
+
+<p>A única coisa interessante que não vimos antes é a função <code>book.bookinstance_set.all()</code>. Este método é "automagicamente" construído pelo Django para retornar o conjunto de registros <code>BookInstance</code> associados com um <code>Book</code> em particular.</p>
+
+<pre class="brush: python notranslate">{% for copy in book.bookinstance_set.all %}
+ &lt;!-- code to iterate across each copy/instance of a book --&gt;
+{% endfor %}</pre>
+
+<p>Este método é necessário porque você declara um campo <code>ForeignKey</code> (um-para-muitos) somente no lado "um" do relacionamento. Como você não faz nada para declarar o relacionamento nos outros modelos ("muitos"), ele não possui nenhum campo para obter o conjunto de registros associados. Para superar esse problema, o Django constrói uma função "pesquisa reversa" chamada de forma apropriada, que você pode usar. O nome da função é construído com letras minúsculas no nome do modelo em que o <code>ForeignKey</code> foi declarado, seguido por <code>_set</code> (i.e. então a função criada em <code>Book</code> é <code>bookinstance_set()</code>).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Aqui usamos <code>all()</code> para obter todos os registros (o padrão). Enquanto você pode usar o método <code>filter()</code> para obter um subconjunto de registros no código, não é possível fazer isso diretamente nos modelos, porque não é possível especificar argumentos para funções.</p>
+
+<p>Observe também que, se você não definir um pedido (na sua class-based view ou modelo), também verá erros do servidor de desenvolvimento como este:</p>
+
+<pre class="notranslate">[29/May/2017 18:37:53] "GET /catalog/books/?page=1 HTTP/1.1" 200 1637
+/foo/local_library/venv/lib/python3.5/site-packages/django/views/generic/list.py:99: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: &lt;QuerySet [&lt;Author: Ortiz, David&gt;, &lt;Author: H. McRaven, William&gt;, &lt;Author: Leigh, Melinda&gt;]&gt;
+ allow_empty_first_page=allow_empty_first_page, **kwargs)
+</pre>
+
+<p>Isso acontece porque o <a href="https://docs.djangoproject.com/pt-br/2.1/topics/pagination/#paginator-objects">objeto paginator</a> espera ver algum ORDER BY sendo executado no seu banco de dados subjacente. Sem ele, não é possível garantir que os registros que estão sendo retornados estejam na ordem certa!<strong> </strong></p>
+
+<p>Este tutorial não atingiu a <strong>Paginação </strong>(ainda, mas em breve), mas como você não pode usar <code>sort_by()</code> e passar um parâmetro (o mesmo com <code>filter()</code> descrito acima), você terá que escolher entre três opções:</p>
+
+<ol>
+ <li>Adicione um <code>ordering</code> dentro de uma declaração <code>class Meta</code> no seu model.</li>
+ <li>Adicione um atributo <code>queryset</code> na sua class-based view, especificando um <code>order_by()</code>.</li>
+ <li>Adicione um método <code>get_queryset</code> à sua class-based view personalisada e também especifique o <code>order_by()</code>.</li>
+</ol>
+
+<p>Se você decidir ir com uma <code>class Meta</code> no model <code>Author</code> (provavelmente não tão flexível quanto personalizar o class-based view, mas fácil o suficiente), você terminará com algo assim:</p>
+
+<pre class="notranslate">class Author(models.Model):
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+ date_of_birth = models.DateField(null=True, blank=True)
+ date_of_death = models.DateField('Died', null=True, blank=True)
+
+ def get_absolute_url(self):
+ return reverse('author-detail', args=[str(self.id)])
+
+ def __str__(self):
+ return f'{self.last_name}, {self.first_name}'
+
+<strong> class Meta:
+ ordering = ['last_name']</strong></pre>
+
+<p>Obviamente, o campo não precisa ser <code>last_name</code>: poderia ser qualquer outro.</p>
+
+<p>E por último, mas não menos importante, você deve classificar por um atributo/coluna que realmente tenha um índice (exclusivo ou não) em seu banco de dados para evitar problemas de desempenho. Obviamente, isso não será necessário aqui (e provavelmente estamos nos adiantando muito) com tão poucos livros (e usuários!), Mas é algo a ser lembrado em projetos futuros.</p>
+</div>
+
+<h2 id="Com_o_que_se_parece_agora">Com o que se parece agora?</h2>
+
+<p>Nesse ponto, deveríamos ter criado tudo o necessário para exibir a lista de livros e as páginas de detalhes do livro. Execute o servidor (<code>python3 manage.py runserver</code>) e abra no seu navegador <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a>.</p>
+
+<div class="warning">
+<p><strong>Aviso:</strong> Não clique em nenhum autor ou link de detalhes do autor ainda - você os criará no desafio!</p>
+</div>
+
+<p>Clique no link <strong>All books</strong> para exibir a lista de livros.</p>
+
+<p><img alt="Book List Page" src="https://mdn.mozillademos.org/files/14049/book_list_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 216px; margin: 0px auto; width: 823px;"></p>
+
+<p>Em seguida, clique no link de um dos seus livros. Se tudo estiver configurado corretamente, você deverá ver algo como a seguinte captura de tela.</p>
+
+<p><img alt="Book Detail Page" src="https://mdn.mozillademos.org/files/14051/book_detail_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 783px; margin: 0px auto; width: 926px;"></p>
+
+<h2 id="Paginação">Paginação</h2>
+
+<p>Se você tiver apenas alguns registros, nossa página da lista de livros ficará bem. No entanto, à medida que você entra nas dezenas ou centenas de registros, a página levará progressivamente mais tempo para carregar (e terá muito conteúdo para navegar com sensatez). A solução para esse problema é adicionar paginação às exibições de lista, reduzindo o número de itens exibidos em cada página.</p>
+
+<p>O Django possui excelente suporte embutido para paginação. Melhor ainda, isso é incorporado às exibições de lista genéricas baseadas em classes, para que você não precise fazer muito para habilitá-lo!</p>
+
+<h3 id="Views">Views</h3>
+
+<p>Abra <strong>catalog/views.py</strong>, e adicionea linha <code>paginate_by</code> mostrado em negrito abaixo.</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+ <strong>paginate_by = 10</strong></pre>
+
+<p>Com essa adição, assim que você tiver mais de 10 registros, a visualização começará a paginar os dados que envia para o modelo. As diferentes páginas são acessadas usando os parâmetros GET - para acessar a página 2, você usaria o URL: <code>/catalog/books/<strong>?page=2</strong></code>.</p>
+
+<h3 id="Templates">Templates</h3>
+
+<p>Agora que os dados estão paginados, precisamos adicionar suporte ao modelo para rolar pelo conjunto de resultados. Como podemos fazer isso em todas as visualizações de lista, faremos isso de uma maneira que possa ser adicionada ao modelo base. </p>
+
+<p>Abra <strong>/locallibrary/catalog/templates/<em>base_generic.html</em></strong> e copie no seguinte bloco de paginação, abaixo do nosso bloco de conteúdo (destacado abaixo em negrito). O código primeiro verifica se a paginação está ativada na página atual. Nesse caso, adiciona os links seguintes e anteriores, conforme apropriado (e o número da página atual).</p>
+
+<pre class="brush: python notranslate">{% block content %}{% endblock %}
+
+<strong>  {% block pagination %}
+    {% if is_paginated %}
+        &lt;div class="pagination"&gt;
+            &lt;span class="page-links"&gt;
+                {% if page_obj.has_previous %}
+                    &lt;a href="\{{ request.path }}?page=\{{ page_obj.previous_page_number }}"&gt;previous&lt;/a&gt;
+                {% endif %}
+                &lt;span class="page-current"&gt;
+                    Page \{{ page_obj.number }} of \{{ page_obj.paginator.num_pages }}.
+                &lt;/span&gt;
+                {% if page_obj.has_next %}
+                    &lt;a href="\{{ request.path }}?page=\{{ page_obj.next_page_number }}"&gt;next&lt;/a&gt;
+                {% endif %}
+            &lt;/span&gt;
+        &lt;/div&gt;
+    {% endif %}
+  {% endblock %} </strong></pre>
+
+<p>O <code>page_obj</code> é um objeto de <a href="https://docs.djangoproject.com/pt-br/2.1/topics/pagination/#paginator-objects">Paginator</a> que existirá se a paginação estiver sendo usada na página atual. Permite obter todas as informações sobre a página atual, as páginas anteriores, quantas páginas existem, etc.</p>
+
+<p>Usamos <code>\{{ request.path }}</code> para obter o URL da página atual para criar os links de paginação. Isso é útil porque é independente do objeto que estamos paginando.</p>
+
+<p>É isso aí!</p>
+
+<h3 id="Com_o_que_se_parece_agora_2">Com o que se parece agora?</h3>
+
+<p>A captura de tela abaixo mostra a aparência da paginação - se você não inseriu mais de 10 títulos no banco de dados, pode testá-lo com mais facilidade, abaixando o número especificado na linha <code>paginate_by</code> no seu arquivo <strong>catalog/views.py</strong>. Para obter o resultado abaixo, alteramos para <code>paginate_by = 2</code>.</p>
+
+<p>Os links de paginação são exibidos na parte inferior, com os links seguinte/anterior, dependendo da página em que você está.</p>
+
+<p><img alt="Book List Page - paginated" src="https://mdn.mozillademos.org/files/14057/book_list_paginated.png" style="border-style: solid; border-width: 1px; display: block; height: 216px; margin: 0px auto; width: 924px;"></p>
+
+<h2 id="Challenge_yourself">Challenge yourself</h2>
+
+<p>The challenge in this article is to create the author detail and list views required to complete the project. These should be made available at the following URLs:</p>
+
+<ul>
+ <li><code>catalog/authors/</code> — The list of all authors.</li>
+ <li><code>catalog/author/<em>&lt;id&gt;</em></code><em> </em>— The detail view for the specific author with a primary key field named <em><code>&lt;id&gt;</code></em></li>
+</ul>
+
+<p>The code required for the URL mappers and the views should be virtually identical to the <code>Book</code> list and detail views we created above. The templates will be different but will share similar behaviour.</p>
+
+<div class="note">
+<p><strong>Note</strong>:</p>
+
+<ul>
+ <li>Once you've created the URL mapper for the author list page you will also need to update the <strong>All authors</strong> link in the base template. Follow the <a href="#Update_the_base_template">same process</a> as we did when we updated the <strong>All books</strong> link.</li>
+ <li>Once you've created the URL mapper for the author detail page, you should also update the <a href="#Creating_the_Detail_View_template">book detail view template</a> (<strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>) so that the author link points to your new author detail page (rather than being an empty URL). The line will change to add the template tag shown in bold below.
+ <pre class="brush: html notranslate">&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; &lt;a href="<strong>{% url 'author-detail' book.author.pk %}</strong>"&gt;\{{ book.author }}&lt;/a&gt;&lt;/p&gt;
+</pre>
+ </li>
+</ul>
+</div>
+
+<p>When you are finished, your pages should look something like the screenshots below.</p>
+
+<p><img alt="Author List Page" src="https://mdn.mozillademos.org/files/14053/author_list_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<ul>
+</ul>
+
+<p><img alt="Author Detail Page" src="https://mdn.mozillademos.org/files/14055/author_detail_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 358px; margin: 0px auto; width: 825px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Summary">Summary</h2>
+
+<p>Congratulations, our basic library functionality is now complete! </p>
+
+<p>In this article, we've learned how to use the generic class-based list and detail views and used them to create pages to view our books and authors. Along the way we've learned about pattern matching with regular expressions, and how you can pass data from URLs to your views. We've also learned a few more tricks for using templates. Last of all we've shown how to paginate list views so that our lists are manageable even when we have many records.</p>
+
+<p>In our next articles, we'll extend this library to support user accounts, and thereby demonstrate user authentication, permissons, sessions, and forms.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/">Built-in class-based generic views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-display/">Generic display views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/intro/">Introduction to class-based views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins">Built-in template tags and filters</a> (Django docs).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/pagination/">Pagination</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Usando models</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Authentication">Tutorial Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/home_page/index.html b/files/pt-br/learn/server-side/django/home_page/index.html
new file mode 100644
index 0000000000..3c7783c352
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/home_page/index.html
@@ -0,0 +1,420 @@
+---
+title: 'Django Tutorial Parte 5: Criando nossa home page'
+slug: Learn/Server-side/Django/Home_page
+tags:
+ - Aprender
+ - Artigo
+ - Codificação
+ - Iniciante
+ - Tutorial
+ - django
+ - django templates
+ - django views
+ - lado servidor (server-side)
+translation_of: Learn/Server-side/Django/Home_page
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Agora estamos prontos para adicionar o código que exibe nossa primeira página completa - uma home page do site <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>. A página inicial mostrará o número de registros que temos para cada tipo de modelo e fornecerá links de navegação na barra lateral para nossas outras páginas. Ao longo do caminho, obteremos experiência prática ao escrever mapas e visualizações básicos de URL, obter registros do banco de dados e usar modelos.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Leia a <a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a>. Conclua os tópicos do tutorial anterior (incluindo <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Aprender a criar mapas e visualizações de URL simples (onde nenhum dado é codificado no URL), obtenha dados de modelos e crie modelos.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Global">Visão Global</h2>
+
+<p>Depois de definirmos nossos modelos e criarmos alguns registros iniciais da biblioteca para trabalhar, é hora de escrever o código que apresenta essas informações aos usuários. A primeira coisa que precisamos fazer é determinar quais informações queremos exibir em nossas páginas e definir os URLs a serem usados para retornar esses recursos. Em seguida, criaremos um mapeador de URLs, visualizações e modelos para exibir as páginas.</p>
+
+<p>O diagrama a seguir descreve o fluxo de dados principal e os componentes necessários ao manipular solicitações e respostas HTTP. Como já implementamos o modelo, os principais componentes que criaremos são:</p>
+
+<ul>
+ <li>Mapeadores de URL para encaminhar os URLs suportados (e qualquer informação codificada nos URLs) para as funções de exibição apropriadas.</li>
+ <li>View functions para obter os dados solicitados dos modelos, crie páginas HTML que exibem os dados e retorne as páginas ao usuário para visualização no navegador.</li>
+ <li>Templates para usar ao renderizar dados nas visualizações.</li>
+</ul>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13931/basic-django.png" style="display: block; margin: 0px auto;"></p>
+
+<p>Como você verá na próxima seção, temos 5 páginas para exibir, o que é muita informação para documentar em um único artigo. Portanto, este artigo se concentrará em como implementar a página inicial e abordaremos as outras páginas em um artigo subsequente. Isso deve fornecer uma boa compreensão completa de como os mapeadores, visualizações e modelos de URL funcionam na prática.</p>
+
+<h2 id="Definindo_os_URLs_do_recurso">Definindo os URLs do recurso</h2>
+
+<p>Como esta versão do <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary </a>é essencialmente somente leitura para usuários finais, precisamos fornecer uma página de destino para o site (uma página inicial) e páginas que exibam visualizações de lista e detalhes de livros e autores.</p>
+
+<p>As URLs que iremos precisar na nossa página são:</p>
+
+<ul>
+ <li><code>catalog/</code> — A página inicial (index).</li>
+ <li><code>catalog/books/</code> — Uma lista de todos os livros.</li>
+ <li><code>catalog/authors/</code> — Uma lista de todos os autores.</li>
+ <li><code>catalog/book/<em>&lt;id&gt;</em></code> — A exibição de detalhes de um livro específico, com uma chave primária de campo <code><em>&lt;id&gt;</em></code> (o padrão). Por exemplo, o URL do terceiro livro adicionado à lista será <code>/catalog/book/3</code>.</li>
+ <li><code>catalog/author/<em>&lt;id&gt;</em></code><em> </em>— A exibição de detalhes para o autor específico com um campo de chave primária de <em><code>&lt;id&gt;.  </code></em>Por exemplo, o URL do 11º autor adicionado à lista será  <code>/catalog/author/11</code>.</li>
+</ul>
+
+<p>Os três primeiros URLs retornarão a página de índice, a lista de livros e a lista de autores. Esses URLs não codificam nenhuma informação adicional e as consultas que buscam dados no banco de dados sempre serão as mesmas. No entanto, os resultados retornados pelas consultas dependerão do conteúdo do banco de dados.</p>
+
+<p>Por outro lado, os dois URLs finais exibirão informações detalhadas sobre um livro ou autor específico. Esses URLs codificam a identidade do item a ser exibido (representado por <code><em>&lt;id&gt;</em></code> acima). O mapeador de URLs extrairá as informações codificadas e as passará para a visualização, e a visualização determinará dinamicamente quais informações serão obtidas do banco de dados. Ao codificar as informações no URL, usaremos um único conjunto de mapeamento de URL, uma visualização e um modelo para lidar com todos os livros (ou autores). </p>
+
+<div class="note">
+<p><strong>Nota</strong>: Com o Django, você pode construir suas URLs da maneira que desejar - você pode codificar informações no corpo da URL, como mostrado acima, ou incluir <code>GET</code> parâmetros no URL, por exemplo <code>/book/?id=6</code>. Qualquer que seja a abordagem usada, os URLs devem ser mantidos limpos, lógicos e legíveis, conforme <a href="https://www.w3.org/Provider/Style/URI">recomendado pelo W3C</a>.<br>
+ A documentação do Django recomenda informações de codificação no corpo da URL para obter um melhor design da URL.</p>
+</div>
+
+<p>Conforme mencionado na visão geral, o restante deste artigo descreve como construir a página index.</p>
+
+<h2 id="Criando_a_página_index">Criando a página index</h2>
+
+<p>A primeira página que criaremos é a página index (<code>catalog/</code>). A pagina index incluirá algum HTML estático, juntamente com "contagens" geradas de diferentes registros no banco de dados. Para fazer isso funcionar, criaremos um mapeamento de URL, uma visualização e um modelo.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Vale a pena prestar um pouco de atenção extra nesta seção. A maioria das informações também se aplica às outras páginas que criaremos.</p>
+</div>
+
+<h3 id="Mapeamento_de_URL">Mapeamento de URL</h3>
+
+<p>Quando criamos o <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">esqueleto do website</a>, atualizamos o arquivo <strong>locallibrary/urls.py</strong> para garantir que sempre que um URL que comece com <code>catalog/</code>  é recebido, o módulo URLConf <code>catalog.urls</code> processará a substring restante.</p>
+
+<p>O seguinte snippet de código de <strong>locallibrary/urls.py </strong>inclui o modulo <code>catalog.urls</code>:</p>
+
+<pre class="notranslate">urlpatterns += [
+    path('catalog/', include('catalog.urls')),
+]
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Sempre que o Django encontra a função de importação  <code><a href="https://docs.djangoproject.com/en/2.1/ref/urls/#django.urls.include" title="django.conf.urls.include">django.urls.include()</a></code>, divide a string da URL no caractere final designado e envia a subsequência restante para o módulo URLconf incluído para processamento adicional.</p>
+</div>
+
+<p>Também criamos um arquivo de espaço reservado para o modulo <em>URLConf</em>, chamado <strong>/catalog/urls.py</strong>. Adicione as seguintes linhas a esse arquivo: </p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+<strong> path('', views.index, name='index'),</strong>
+]</pre>
+
+<p>A função <code>path()</code> define o seguinte:</p>
+
+<ul>
+ <li>Um padrão de URL, que é uma sequência vazia: <code>''</code>. Discutiremos detalhadamente os padrões de URL ao trabalhar em outras visualizações.</li>
+ <li>A view function that will be called if the URL pattern is detected: <code>views.index</code>,  which is the function named <code>index()</code> in the <strong>views.py </strong>file. </li>
+</ul>
+
+<p>A função <code>path()</code> também especifica um parâmetro de nome, que é um identificador exclusivo para esse mapeamento de URL específico. Você pode usar o nome para "reverter" o mapeador, ou seja, para criar dinamicamente um URL que aponte para o recurso que o mapeador foi projetado para manipular. Por exemplo, podemos usar o parâmetro name para vincular à nossa home page a partir de qualquer outra página adicionando o seguinte link em um modelo:</p>
+
+<pre class="brush: html notranslate">&lt;a href="<strong>{% url 'index' %}</strong>"&gt;Home&lt;/a&gt;.</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Podemos codificar o link como em <code>&lt;a href="<strong>/catalog/</strong>"&gt;Home&lt;/a&gt;</code>), mas se alterarmos o padrão da nossa página inicial, por exemplo, para <code>/catalog/index</code>) os modelos não serão mais vinculados corretamente. Usar um mapeamento de URL invertido é muito mais flexível e robusto.</p>
+</div>
+
+<h3 id="View_function-based">View (function-based)</h3>
+
+<p>Uma view é uma função que processa uma solicitação HTTP, busca os dados necessários no banco de dados, renderiza os dados em uma página HTML usando um modelo HTML e, em seguida, retorna o HTML gerado em uma resposta HTTP para exibir a página ao usuário. A visualização do índice segue esse modelo - ele busca informações sobre o número de <code>Book</code>, <code>BookInstance</code>, disponibilidade de  <code>BookInstance</code> e registros de <code>Author</code> que temos no banco de dados e passa essas informações para um modelo para exibição.</p>
+
+<p>Abra <strong>catalog/views.py</strong> e observe que o arquivo já importa o <a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#django.shortcuts.render">render()</a> da função shortcuts para gerar arquivo HTML usando um modelo e dados: </p>
+
+<pre class="brush: python notranslate">from django.shortcuts import render
+
+# Create your views here.
+</pre>
+
+<p>Cole as seguintes linhas na parte inferior do arquivo:</p>
+
+<pre class="brush: python notranslate">from catalog.models import Book, Author, BookInstance, Genre
+
+def index(request):
+ """View function for home page of site."""
+
+ # Generate counts of some of the main objects
+ num_books = Book.objects.all().count()
+ num_instances = BookInstance.objects.all().count()
+
+ # Available books (status = 'a')
+ num_instances_available = BookInstance.objects.filter(status__exact='a').count()
+
+ # The 'all()' is implied by default.
+ num_authors = Author.objects.count()
+
+ context = {
+ 'num_books': num_books,
+ 'num_instances': num_instances,
+ 'num_instances_available': num_instances_available,
+ 'num_authors': num_authors,
+ }
+
+ # Render the HTML template index.html with the data in the context variable
+ return render(request, 'index.html', context=context)</pre>
+
+<p>A primeira linha importa as classes de models que usaremos para acessar dados em todas as nossas visualizações.</p>
+
+<p>A primeira parte da função view busca o número de registros usando o atributo  <code>objects.all()</code> nas classes de modelo. Também recebe uma lista de objetos de  <code>BookInstance</code> que possuem um valor de 'a' (Disponibilidade) no campo status. Você pode encontrar mais informações sobre como acessar os dados do modelo em nosso tutorial anterior <a href="/en-US/docs/Learn/Server-side/Django/Models#Searching_for_records">Django Tutorial Part 3: Using models &gt; Searching for records</a>.</p>
+
+<p>No final da função view chamamos a função <code>render()</code> para criar uma página HTML e retornar a página como resposta. essa função de atalho envolve várias outras funções para simplificar um caso de uso muito comum. A função <code>render()</code> aceita os seguintes parâmetros:</p>
+
+<ul>
+ <li>o objeto <code>request</code> original, que é um <code>HttpRequest</code>.</li>
+ <li>um modelo HTML com espaços reservados para os dados.</li>
+ <li>uma variável <code>context</code>, que é um dicionário Python, contendo os dados a serem inseridos nos espaços reservados. </li>
+</ul>
+
+<p>Falaremos mais sobre modelos e variáveis <code>context</code> na próxima seção. Vamos criar nosso template para que possamos exibir algo para o usuário!</p>
+
+<h3 id="Template">Template</h3>
+
+<p>Um template é um arquivo de texto que define a estrutura ou o layout de um arquivo (como uma página HTML), usa espaços reservados para representar o conteúdo real.</p>
+
+<p>Django irá procurar automaticamente templates na pasta chamada '<strong>templates</strong>' em sua aplicação. Por exemplo, na exibição de index que acabamos de adicionar, a função <code>render()</code> espera encontrar o arquivo <em><strong>index.html</strong> em</em><em> </em><strong>/locallibrary/catalog/templates/</strong> e gera um erro se o arquivo não estiver presente.</p>
+
+<p>Você pode verificar isso salvando as alterações anteriores e acessando <code>127.0.0.1:8000</code> no seu navegador - ele exibirá uma mensagem de erro bastante intuitiva: "<code>TemplateDoesNotExist at /catalog/</code>", e outros detalhes.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Com base no arquivo de configurações do seu projeto, o Django procurará templates em vários locais, pesquisando nos aplicativos instalados por padrão. Você pode descobrir mais sobre como o Django encontra templates e quais formatos ele suporta no <a href="https://docs.djangoproject.com/en/2.1/topics/templates/">the Templates section of the Django documentation</a>.</p>
+</div>
+
+<h4 id="Estendendo_templates">Estendendo templates</h4>
+
+<p>O index template precisará de marcação HTML padrão para head e a body, juntamente com as seções de navegação para criar um link para as outras páginas do site (que ainda não criamos) e para as seções que exibem dados introdutórios de texto e livro.</p>
+
+<p>Grande parte da estrutura HTML e de navegação será a mesma em todas as páginas do nosso site. Em vez de duplicar o código padrão em todas as páginas, você pode usar a linguagem de modelagem do Django para declarar um modelo base e depois estendê-lo para substituir apenas os bits que são diferentes para cada página específica.</p>
+
+<p>O seguinte snippet de código é um template base de amostra de um arquivo <strong>base_generic.html</strong>. Em breve, criaremos o modelo para a LocalLibrary. O exemplo abaixo inclui HTML comum com seções para um título, uma barra lateral e o conteúdo principal marcado com as template tags de nome <code>block</code> e <code>endblock</code>, mostrado em negrito. Você pode deixar os blocos vazios ou incluir o conteúdo padrão a ser usado ao renderizar páginas derivadas do modelo.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Template <em>tags</em> são funções que você pode usar em um modelo para percorrer as listas, executar operações condicionais com base no valor de uma variável e assim por diante. Além das template tags, a sintaxe template permite que você faça referência a variáveis que são passadas para a template a partir da view e use filtros de template para formatar variáveis (por exemplo, para converter uma sequência em minúscula).</p>
+</div>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+&lt;head&gt;
+ <strong>{% block title %}</strong>&lt;title&gt;Local Library&lt;/title&gt;<strong>{% endblock %}</strong>
+&lt;/head&gt;
+&lt;body&gt;
+ <strong>{% block sidebar %}</strong>&lt;!-- insert default navigation text for every page --&gt;<strong>{% endblock %}</strong>
+ <strong>{% block content %}</strong>&lt;!-- default content text (typically empty) --&gt;<strong>{% endblock %}</strong>
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>Ao definir um template para uma visualização específica, primeiro especificamos o template base usando a template tag <code>extends</code> — veja o exemplo de código abaixo. Em seguida, declaramos quais seções do template queremos substituir (se houver), usando seções <code>block</code>/<code>endblock</code> como no template base. </p>
+
+<p>Por exemplo, o trecho de código abaixo mostra como usar a template tag <code>extends</code> e substituir o block <code>content</code>. O HTML gerado incluirá o código e a estrutura definidos no template base, incluindo o conteúdo padrão que você definiu no block <code>title</code>, mas o novo block <code>content</code> no lugar do padrão.</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Local Library Home&lt;/h1&gt;
+ &lt;p&gt;Welcome to LocalLibrary, a website developed by &lt;em&gt;Mozilla Developer Network&lt;/em&gt;!&lt;/p&gt;
+{% endblock %}</pre>
+
+<h4 id="O_template_base_LocalLibrary">O template base LocalLibrary</h4>
+
+<p>Usaremos o seguinte snippet de código como modelo básico para o site <em>LocalLibrary</em>. Como você pode ver, ele contém algum código HTML e define blocos para <code>title</code>, <code>sidebar</code>, e <code>content</code>. Temos um título padrão e uma barra lateral padrão com links para listas de todos os livros e autores, ambos colocados em blocos para serem facilmente alterados no futuro.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Também introduzimos duas template tags adicionais: <code>url</code> e <code>load static</code>. Essas tags serão explicadas nas próximas seções.</p>
+</div>
+
+<p>Crie um novo arquivo <strong><em>base_generic.html </em></strong>em <strong>/locallibrary/catalog/templates/</strong> e cole o seguinte código no arquivo:</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+&lt;head&gt;
+ {% block title %}&lt;title&gt;Local Library&lt;/title&gt;{% endblock %}
+ &lt;meta charset="utf-8"&gt;
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
+ &lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"&gt;
+ &lt;!-- Add additional CSS in static file --&gt;
+ {% load static %}
+ &lt;link rel="stylesheet" href="{% static 'css/styles.css' %}"&gt;
+&lt;/head&gt;
+&lt;body&gt;
+ &lt;div class="container-fluid"&gt;
+ &lt;div class="row"&gt;
+ &lt;div class="col-sm-2"&gt;
+ {% block sidebar %}
+ &lt;ul class="sidebar-nav"&gt;
+ &lt;li&gt;&lt;a href="{% url 'index' %}"&gt;Home&lt;/a&gt;&lt;/li&gt;
+ &lt;li&gt;&lt;a href=""&gt;All books&lt;/a&gt;&lt;/li&gt;
+ &lt;li&gt;&lt;a href=""&gt;All authors&lt;/a&gt;&lt;/li&gt;
+ &lt;/ul&gt;
+ {% endblock %}
+ &lt;/div&gt;
+ &lt;div class="col-sm-10 "&gt;{% block content %}{% endblock %}&lt;/div&gt;
+ &lt;/div&gt;
+ &lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>O template inclui CSS de <a href="http://getbootstrap.com/">Bootstrap</a> para melhorar o layout e a apresentação da página HTML. O uso do Bootstrap (ou outra estrutura da Web do lado do cliente) é uma maneira rápida de criar uma página atraente que é exibida bem em diferentes tamanhos de tela.</p>
+
+<p>O template base também faz referência a um arquivo css local (<strong>styles.css</strong>) que fornece estilo adicional. Criar um arquivo <strong>styles.css </strong>em<strong> </strong><strong>/locallibrary/catalog/static/css/</strong> e cole o seguinte código no arquivo:</p>
+
+<pre class="brush: css notranslate">.sidebar-nav {
+ margin-top: 20px;
+ padding: 0;
+ list-style: none;
+}</pre>
+
+<h4 id="O_template_index">O template index</h4>
+
+<p>Crie um novo arquivo HTML <strong><em>index.html </em></strong>em <strong>/locallibrary/catalog/templates/</strong> e cole o seguinte código no arquivo Esse código estende nosso modelo base na primeira linha e substitui o padrão block <code>content</code> para o template. </p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Local Library Home&lt;/h1&gt;
+ &lt;p&gt;Welcome to LocalLibrary, a website developed by &lt;em&gt;Mozilla Developer Network&lt;/em&gt;!&lt;/p&gt;
+ &lt;h2&gt;Dynamic content&lt;/h2&gt;
+ &lt;p&gt;The library has the following record counts:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li&gt;&lt;strong&gt;Books:&lt;/strong&gt; <strong>\{{ num_books }}</strong>&lt;/li&gt;
+ &lt;li&gt;&lt;strong&gt;Copies:&lt;/strong&gt; <strong>\{{ num_instances }}</strong>&lt;/li&gt;
+ &lt;li&gt;&lt;strong&gt;Copies available:&lt;/strong&gt; <strong>\{{ num_instances_available }}</strong>&lt;/li&gt;
+ &lt;li&gt;&lt;strong&gt;Authors:&lt;/strong&gt; <strong>\{{ num_authors }}</strong>&lt;/li&gt;
+ &lt;/ul&gt;
+{% endblock %}</pre>
+
+<p>Na seção <em>Dynamic content</em>, declaramos espaços reservados (<em>variáveis de template</em>) para as informações da exibição que queremos incluir. As variáveis são colocadas entre chaves (guiador), como mostrado em negrito no exemplo de código. </p>
+
+<div class="note">
+<p><strong>Nota:</strong> Você pode reconhecer facilmente variáveis de template e template tags (funções) - as variáveis são colocadas entre chaves (<code>\{{ num_books }}</code>), e as tags são colocadas em chaves simples com sinais de porcentagem (<code>{% extends "base_generic.html" %}</code>).</p>
+</div>
+
+<p>O importante a ser observado aqui é que as variáveis são nomeadas com as <em>chaves</em> que passamos para o dicionário <code>context</code> na função <code>render()</code> da nossa view (veja a amostra abaixo). As variáveis serão substituídas pelos <em>valores </em>associados quando o modelo for renderizado.</p>
+
+<pre class="brush: python notranslate">context = {
+ '<strong>num_books</strong>': num_books,
+ '<strong>num_instances</strong>': num_instances,
+ '<strong>num_instances_available</strong>': num_instances_available,
+ '<strong>num_authors</strong>': num_authors,
+}
+
+return render(request, 'index.html', context=context)</pre>
+
+<h4 id="Referenciando_arquivos_estáticos_nos_templates">Referenciando arquivos estáticos nos templates</h4>
+
+<p>É provável que seu projeto use recursos estáticos, incluindo JavaScript, CSS e imagens. Como a localização desses arquivos pode não ser conhecida (ou pode mudar), o Django permite que você especifique a localização em seus modelos em relação a configuração global <code>STATIC_URL</code>. O site padrão do esqueleto define o valor de <code>STATIC_URL</code> para '<code>/static/</code>', mas você pode optar por hospedá-los em uma rede de entrega de conteúdo ou em outro local.</p>
+
+<p>Dentro do template que você chama primeiro na template tag <code>load</code> especificando "static" para adicionar a biblioteca de modelos, conforme mostrado no exemplo de código abaixo. Você pode então usar a template tag <code>static</code> e especifique o URL relativo ao arquivo necessário.</p>
+
+<pre class="brush: html notranslate">&lt;!-- Add additional CSS in static file --&gt;
+{% load static %}
+&lt;link rel="stylesheet" href="{% static 'css/styles.css' %}"&gt;</pre>
+
+<p>Você pode adicionar uma imagem à página de maneira semelhante, por exemplo:</p>
+
+<pre class="brush: html notranslate">{% load static %}
+&lt;img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="UML diagram" style="width:555px;height:540px;"&gt;
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Os exemplos acima especificam onde os arquivos estão localizados, mas o Django não os serve por padrão. Configuramos o servidor da web de desenvolvimento para exibir arquivos modificando o mapeador de URL global (<strong>/locallibrary/locallibrary/urls.py</strong>) quando <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">criamos o esqueleto do website</a>, mas ainda precisamos ativar a veiculação de arquivos na produção. Veremos isso mais tarde.</p>
+</div>
+
+<p>Para obter mais informações sobre como <a href="https://docs.djangoproject.com/en/2.1/howto/static-files/">Trabalhar com arquivos estaticos</a>, consulte Gerenciando arquivos estáticos na documentação do Django.</p>
+
+<h4 id="Vinculando_as_URLs">Vinculando as URLs</h4>
+
+<p>O template base abaixo introduziu a template tag <code>url</code>.</p>
+
+<pre class="brush: python notranslate">&lt;li&gt;&lt;a href="{% url 'index' %}"&gt;Home&lt;/a&gt;&lt;/li&gt;
+</pre>
+
+<p>Essa tag aceita o nome de uma função <code>path()</code> chamado em <strong>urls.py</strong> e os valores para quaisquer argumentos que a view associada receberá dessa função e retorna um URL que você pode usar para vincular ao recurso.</p>
+
+<h4 id="Configurando_onde_encontrar_os_templates">Configurando onde encontrar os templates</h4>
+
+<p>Você precisa dizer ao Django para procurar seus templates na pasta de templates. Para fazer isso, adicione o diretório de templates ao objeto TEMPLATES editando o arquivo <strong>settings.py</strong>, como mostrado em negrito, no seguinte exemplo de código:</p>
+
+<pre class="brush: python notranslate">TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [
+<strong>            os.path.join(BASE_DIR, 'templates'),
+</strong>        ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]</pre>
+
+<h2 id="Com_o_que_se_parece">Com o que se parece?</h2>
+
+<p>Neste ponto, criamos todos os recursos necessários para exibir a página index. Execute o servidor (<code>python3 manage.py runserver</code>) e abra <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a> no seu navegador. Se tudo estiver configurado corretamente, seu site deverá ter a seguinte captura de tela.</p>
+
+<p><img alt="Index page for LocalLibrary website" src="https://mdn.mozillademos.org/files/14045/index_page_ok.png" style="border-style: solid; border-width: 1px; display: block; height: 356px; margin: 0px auto; width: 874px;"></p>
+
+<div class="note">
+<p><strong>Nota:</strong> Os links <strong>All books</strong> e <strong>All authors</strong> ainda não funcionarão porque os caminhos, visualizações e modelos para essas páginas não estão definidos. Acabamos de inserir espaços reservados para esses links no template <code>base_generic.html</code>.</p>
+</div>
+
+<h2 id="Desafie-se">Desafie-se</h2>
+
+<p>Temos duas tarefas para testar a sua familiaridade com as consultas de modelos, views e templates</p>
+
+<ol>
+ <li>O modelo de <a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Home_page#The_LocalLibrary_base_template">base</a> da BibliotecaLocal inclui um bloco de <code>título</code>. Substitua este bloco no modelo de índice e crie um novo título para a página.</li>
+ <li>
+ <div class="note">
+ <p><strong>Dica: </strong>A seção<a href="#Extending_templates"> Extendendo Templates</a> explica como criar blocos e  extender um bloco em outro template.</p>
+ </div>
+ </li>
+ <li>Modifique a <a href="#View_(function-based)">view</a> para gerar contagens para gêneros e livros que contenham uma palavra específica (case insensitive), e passe o resultado para o <code>contexto.</code> <span class="tlid-translation translation" lang="pt"><span title="">Isso é feito de maneira semelhante à criação e uso de <code>num_books</code> e <code>num_instances_available</code>.</span> <span title="">Em seguida, atualize o template do index para incluir essas variáveis.</span></span></li>
+</ol>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Acabamos de criar a página inicial do nosso site - uma página HTML que exibe uma série de registros do banco de dados e links para outras páginas ainda a serem criadas. Ao longo do caminho, aprendemos informações fundamentais sobre mapeadores de url, views, consulta do banco de dados com modelos, passagem de informações para um modelo a partir de uma view e criação e extensão de templates.</p>
+
+<p>No próximo artigo, continuaremos sobre esse conhecimento para criar as quatro páginas restantes de nosso site.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/pt-br/3.1/intro/tutorial03/">Escrevendo sua primeira aplicação Django, parte 3: View e Templates</a> (documentação do Django)</li>
+ <li><a href="https://docs.djangoproject.com/pt-br/3.1/topics/http/urls/">Despachante de URL</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/pt-br/3.1/topics/http/views/">Funções das Views </a> (DJango docs)</li>
+ <li><a href="https://docs.djangoproject.com/pt-br/3.1/topics/templates/">Templates</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/static-files/">Gerenciando arquivos estáticos</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#django.shortcuts.render">Funções de atalho do Django</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Nesse_Módulo">Nesse Módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Utilizando models</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Sessões de Framework </a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/web_application_security">Segurança de aplicações web Django</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/hospedagem/index.html b/files/pt-br/learn/server-side/django/hospedagem/index.html
new file mode 100644
index 0000000000..baa2217b71
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/hospedagem/index.html
@@ -0,0 +1,692 @@
+---
+title: 'Tutorial Django Parte 11: Hospedando Django para produção'
+slug: Learn/Server-side/Django/Hospedagem
+tags:
+ - Codificação de Scripts
+ - Deploy do django
+ - Fazendo deploy
+ - Iniciante
+ - django
+ - servidor web
+translation_of: Learn/Server-side/Django/Deployment
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Agora que criou (e testou) um fantástico website de Biblioteca Local, vai querer instalá-lo em um servidor web público para que possa ser acessado pelo pessoal da biblioteca e membros através da Internet. Este artigo fornece uma visão geral de como poderá encontrar um servidor de hospedagem para instalar o seu web site, e o que precisa fazer para ter o seu site web pronto para produção.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>
+ <p>Completar todos os tópicos do tutorial anterior, incluindo o <a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django.</a></p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectivo:</th>
+ <td>Para saber onde e como se pode hospedar uma aplicação Django na produção.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_geral">Visão geral</h2>
+
+<p>Uma vez terminado o seu website (ou terminado "o suficiente" para iniciar testes públicos) vai precisar publicá-lo em um host mais público e acessível do que o seu computador de desenvolvimento pessoal.</p>
+
+<p>Até agora tem trabalhado em um ambiente de desenvolvimento, utilizando o servidor web de desenvolvimento Django para compartilhar o seu site com o navegador/rede local, e executando o seu site com configurações de desenvolvimento (inseguras) que expõem debug e outras informações privadas. Antes de poder hospedar um website externamente, vai precisar fazer primeiro:</p>
+
+<ul>
+ <li>Faça algumas alterações nas configurações do seu projeto.</li>
+ <li>Escolher um ambiente para hospedar a aplicação Django.</li>
+ <li>Escolher um ambiente para hospedar qualquer arquivo estático.</li>
+ <li>Configurar uma infraestrutura de nível de produção para servir seu website.</li>
+</ul>
+
+<p>Este tutorial fornece algumas orientações sobre suas opções para escolher um site de hospedagem, uma breve visão geral do que você precisa fazer para deixar seu aplicativo Django pronto para produção e um exemplo prático de como instalar o site Biblioteca Local no serviço de hospedagem em nuvem do <a href="https://www.heroku.com/">Heroku.</a></p>
+
+<h2 id="O_que_é_um_ambiente_de_produção">O que é um ambiente de produção?</h2>
+
+<p>O ambiente de produção é o ambiente fornecido pelo computador/servidor onde você executará seu site para consumo externo. O ambiente inclui:</p>
+
+<ul>
+ <li>Hardware de computador no qual o website é executado.</li>
+ <li>Sistema operacional (por exemplo, Linux, Windows).</li>
+ <li>Linguagem de programação de tempo de execução e bibliotecas de estrutura sobre as quais seu site é escrito.</li>
+ <li>Servidor da Web usado para servir páginas e outros conteúdos (por exemplo, Nginx, Apache).</li>
+ <li>Servidor de aplicativos que passa solicitações "dinâmicas" entre seu site Django e o servidor web.</li>
+ <li>Bancos de dados dos quais seu site depende.</li>
+</ul>
+
+<div class="note">
+<p><strong>Nota: </strong>Dependendo de como sua produção está configurada, você também pode ter um proxy reverso, load balancer(balanceador de carga), etc.</p>
+</div>
+
+<p>O computador/servidor pode estar localizado em suas instalações e conectado à Internet por um link rápido, mas é muito mais comum usar um computador hospedado "na nuvem". O que isso realmente significa é que seu código é executado em algum computador remoto (ou possivelmente em um computador "virtual") no(s) centro(s) de dados da empresa de hospedagem. O servidor remoto geralmente oferece algum nível garantido de recursos de computação (por exemplo, CPU, RAM, memória de armazenamento, etc.) e conectividade com a Internet por um determinado preço.</p>
+
+<p>Esse tipo de hardware de computação/rede acessível remotamente é conhecido como <em>Infraestrutura como Serviço</em> (IaaS). Muitos fornecedores de IaaS fornecem opções para pré-instalar um sistema operacional específico, no qual você deve instalar os outros componentes de seu ambiente de produção. Outros fornecedores permitem que você selecione ambientes com mais recursos, talvez incluindo uma configuração completa de Django e servidor web.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Ambientes pré-construídos podem tornar a configuração do seu site muito fácil porque reduzem a configuração, mas as opções disponíveis podem limitar você a um servidor desconhecido (ou outros componentes) e podem ser baseadas em uma versão mais antiga do sistema operacional. Freqüentemente, é melhor instalar você mesmo os componentes, para obter os que deseja e, quando precisar atualizar partes do sistema, tenha uma ideia de por onde começar!</p>
+</div>
+
+<p>Outros provedores de hospedagem oferecem suporte a Django como parte de uma oferta de <em>Plataforma como Serviço</em> (PaaS). Nesse tipo de hospedagem, você não precisa se preocupar com a maior parte do seu ambiente de produção (servidor da web, servidor de aplicativos, balanceadores de carga), pois a plataforma host cuida disso para você (junto com a maior parte do que você precisa fazer para para dimensionar seu aplicativo). Isso torna a implantação muito fácil, porque você só precisa se concentrar em seu aplicativo da web e não em toda a outra infraestrutura de servidor.</p>
+
+<p>Alguns desenvolvedores escolherão a maior flexibilidade fornecida por IaaS em vez de PaaS, enquanto outros apreciarão a sobrecarga de manutenção reduzida e escalonamento mais fácil de PaaS. Quando você está começando, configurar seu site em um sistema PaaS é muito mais fácil e é isso que faremos neste tutorial.</p>
+
+<div class="note">
+<p><strong>Dica:</strong> Se você escolher um provedor de hospedagem compatível com Python / Django, ele deve fornecer instruções sobre como configurar um site Django usando diferentes configurações de servidor da web, servidor de aplicativos, proxy reverso, etc (isso não será relevante se você escolher um PaaS ) Por exemplo, existem muitos guias passo a passo para várias configurações nos <a href="https://www.digitalocean.com/community/tutorials?q=django">documentos da comunidade Digital Ocean Django.</a></p>
+</div>
+
+<h2 id="Escolhendo_um_provedor_de_hospedagem">Escolhendo um provedor de hospedagem</h2>
+
+<p>Existem mais de 100 provedores de hospedagem que são conhecidos por oferecer suporte ativo ou funcionar bem com o Django (você pode encontrar uma lista bastante exaustiva em <a href="https://djangofriendly.com/index.html">Djangofriendly hosts</a>). Esses fornecedores oferecem diferentes tipos de ambientes (IaaS, PaaS) e diferentes níveis de recursos de computação e rede a preços diferentes.</p>
+
+<p>Algumas coisas a serem consideradas ao escolher um host:</p>
+
+<ul>
+ <li>O quão ocupado seu site provavelmente estará e o custo dos dados e recursos de computação necessários para atender a essa demanda.</li>
+ <li>Nível de suporte para escalonamento horizontal (adicionando mais máquinas) e verticalmente (atualizando para máquinas mais potentes) e os custos de fazê-lo.</li>
+ <li>Onde o fornecedor possui centros de dados e, portanto, onde o acesso provavelmente será mais rápido.</li>
+ <li>O histórico de tempo de atividade e desempenho do tempo de inatividade do host.</li>
+ <li>Ferramentas fornecidas para gerenciar o site - são fáceis de usar e seguras (por exemplo, SFTP x FTP).</li>
+ <li>Estruturas integradas para monitorar seu servidor.</li>
+ <li>Limitações conhecidas. Alguns hosts bloqueiam deliberadamente certos serviços (por exemplo, e-mail). Outros oferecem apenas um certo número de horas de "tempo de vida" em algumas faixas de preço ou oferecem apenas uma pequena quantidade de armazenamento.</li>
+ <li>Benefícios adicionais. Alguns provedores oferecem nomes de domínio gratuitos e suporte para certificados SSL que, de outra forma, você teria que pagar.</li>
+ <li>Se o nível "gratuito" com o qual você está contando expira com o tempo e se o custo de migrar para um nível mais caro significa que você teria ficado melhor usando algum outro serviço em primeiro lugar!</li>
+</ul>
+
+<p>A boa notícia quando você está começando é que existem alguns sites que fornecem ambientes de computação de "avaliação", "desenvolvedor" ou "amador" de graça. Esses são sempre ambientes com recursos limitados / restritos e você precisa estar ciente de que eles podem expirar após um período introdutório. No entanto, eles são ótimos para testar sites de baixo tráfego em um ambiente real e podem fornecer uma migração fácil para pagar por mais recursos quando seu site ficar mais ocupado. As escolhas populares nesta categoria incluem <a href="https://www.heroku.com/">Heroku</a>, <a href="https://www.pythonanywhere.com/">Python Anywhere</a>, <a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/billing-free-tier.html">Amazon Web Services</a>, <a href="https://azure.microsoft.com/en-us/pricing/details/app-service/windows/">Microsoft Azure</a>, etc.</p>
+
+<p>Muitos provedores também têm uma camada "básica" que fornece níveis mais úteis de capacidade de computação e menos limitações. <a href="https://www.digitalocean.com/">Digital Ocean</a> e <a href="https://www.pythonanywhere.com/">Python Anywhere</a> são exemplos de provedores de hospedagem populares que oferecem uma camada de computação básica relativamente barata (na faixa de US$5 a US$10 por mês).</p>
+
+<div class="note">
+<p><strong>Nota: </strong>Lembre-se de que o preço não é o único critério de seleção. Se o seu site for bem-sucedido, pode ser que a escalabilidade seja a consideração mais importante.</p>
+</div>
+
+<h2 id="Preparando_seu_site_para_publicação">Preparando seu site para publicação</h2>
+
+<p>O <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Server-side/Django/skeleton_website">esqueleto do site do Django</a> criado usando as ferramentas django-admin e manage.py é configurado para tornar o desenvolvimento mais fácil. Muitas das configurações do projeto Django (especificadas em settings.py) devem ser diferentes para produção, por motivos de segurança ou desempenho.</p>
+
+<div class="note">
+<p><strong>Dica:</strong> É comum ter um arquivo <strong>settings.py</strong> separado para produção e importar configurações confidenciais de um arquivo separado ou de uma variável de ambiente. Este arquivo deve ser protegido, mesmo se o resto do código-fonte estiver disponível em um repositório público.</p>
+</div>
+
+<p>As configurações críticas que você deve verificar são:</p>
+
+<ul>
+ <li><code>DEBUG</code>. Isso deve ser definido como <code>False</code> em produção (<code>DEBUG = False</code>). Isso impede que o rastreamento de depuração sensível/confidencial e as informações variáveis ​​sejam exibidas.</li>
+ <li><code>SECRET_KEY</code>. Este é um grande valor aleatório usado para proteção contra CSRF etc. É importante que a chave usada na produção não esteja no controle de origem ou acessível fora do servidor de produção. Os documentos do Django sugerem que isso pode ser melhor carregado de uma variável de ambiente ou lido de um arquivo somente servidor.
+ <pre class="brush: python notranslate"># Read SECRET_KEY from an environment variable
+import os
+SECRET_KEY = os.environ['SECRET_KEY']
+
+# OR
+
+# Read secret key from a file
+with open('/etc/secret_key.txt') as f:
+ SECRET_KEY = f.read().strip()</pre>
+ </li>
+</ul>
+
+<p>Vamos mudar o aplicativo LocalLibrary para que possamos ler nosso <code>SECRET_KEY</code> e <code>DEBUG</code> variáveis ​​de variáveis ​​de ambiente se forem definidas, mas caso contrário, use os valores padrão no arquivo de configuração.</p>
+
+<p>Abra <strong>/locallibrary/settings.py</strong>, desative o original <code>SECRET_KEY</code>configuração e adicione as novas linhas conforme mostrado abaixo em <strong>negrito</strong>. Durante o desenvolvimento, nenhuma variável de ambiente será especificada para a chave, então o valor padrão será usado (não importa qual chave você usa aqui, ou se a chave "vaza", porque você não a usará na produção).</p>
+
+<pre class="brush: python notranslate"># SECURITY WARNING: keep the secret key used in production secret!
+# SECRET_KEY = 'cg#p$g+j9tax!#a3cup@1$8obt2_+&amp;k3q+pmu)5%asj6yjpkag'
+<strong>import os</strong>
+<strong>SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'cg#p$g+j9tax!#a3cup@1$8obt2_+&amp;k3q+pmu)5%asj6yjpkag')</strong>
+</pre>
+
+<p>Em seguida, comente o existente <code>DEBUG</code> configuração e adicione a nova linha mostrada abaixo.</p>
+
+<pre class="brush: python notranslate"># SECURITY WARNING: don't run with debug turned on in production!
+# DEBUG = True
+<strong>DEBUG = os.environ.get('DJANGO_DEBUG', '') != 'False'</strong>
+</pre>
+
+<p>O valor do <code>DEBUG</code> será <code>True</code> por padrão, mas será apenas <code>False</code> se o valor do <code>DJANGO_DEBUG</code> variável de ambiente é definida para <code>False</code>. Observe que as variáveis ​​de ambiente são strings e não tipos Python. Portanto, precisamos comparar strings. A única maneira de definir o <code>DEBUG</code> variável para <code>False</code> é realmente configurá-lo para a string <code>False</code></p>
+
+<p>Você pode definir a variável de ambiente como False, emitindo o seguinte comando:</p>
+
+<pre class="brush: bash notranslate">export DJANGO_DEBUG=False</pre>
+
+<p>Uma lista de verificação completa das configurações que você pode querer mudar é fornecida na <a href="https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/">Lista de verificação de implantação</a> (documentos do Django). Você também pode listar vários deles usando o comando de terminal abaixo:</p>
+
+<pre class="brush: python notranslate">python3 manage.py check --deploy
+</pre>
+
+<h2 id="Exemplo_Instalando_LocalLibrary_no_Heroku">Exemplo: Instalando LocalLibrary no Heroku</h2>
+
+<p>Esta seção fornece uma demonstração prática de como instalar a LocalLibrary na nuvem <a href="https://www.heroku.com/">Heroku PaaS.</a></p>
+
+<h3 id="Por_que_Heroku">Por que Heroku?</h3>
+
+<p>Heroku é um dos mais antigos e populares serviços de PaaS baseados em nuvem. Originalmente, ele suportava apenas aplicativos Ruby, mas agora pode ser usado para hospedar aplicativos de muitos ambientes de programação, incluindo Django!</p>
+
+<p>Estamos optando por usar o Heroku por vários motivos:</p>
+
+<ul>
+ <li>O Heroku tem um <a href="https://www.heroku.com/pricing">nível gratuito</a> que é realmente gratuito (embora com algumas limitações).</li>
+ <li>Como PaaS, o Heroku cuida de grande parte da infraestrutura web para nós. Isso torna muito mais fácil começar, porque você não se preocupa com servidores, balanceadores de carga, proxies reversos ou qualquer outra infraestrutura web que o Heroku fornece para nós nos bastidores.</li>
+ <li>Embora tenha algumas limitações, elas não afetarão este aplicativo específico. Por exemplo:
+ <ul>
+ <li>O Heroku fornece apenas armazenamento de curta duração, portanto, os arquivos carregados pelo usuário não podem ser armazenados com segurança no próprio Heroku.</li>
+ <li>O nível gratuito suspenderá um aplicativo da web inativo se não houver solicitações dentro de um período de meia hora. O site pode levar vários segundos para responder quando for ativado.</li>
+ <li>O nível gratuito limita o tempo de execução do seu site a uma determinada quantidade de horas todos os meses (sem incluir o tempo em que o site fica "adormecido"). Isso é bom para um site de baixo uso/demonstração, mas não será adequado se 100% de tempo de atividade for necessário.</li>
+ <li>Outras limitações estão listadas em <a href="https://devcenter.heroku.com/articles/limits">Limites</a> (documentos do Heroku).</li>
+ </ul>
+ </li>
+ <li>Na maioria das vezes, ele simplesmente funciona e, se você acabar adorando, dimensionar seu aplicativo é muito fácil.</li>
+</ul>
+
+<p>Embora o Heroku seja perfeito para hospedar esta demonstração, pode não ser perfeito para o seu site real. O Heroku torna as coisas fáceis de configurar e escalar, ao custo de ser menos flexível e potencialmente muito mais caro depois que você sai do nível gratuito.</p>
+
+<h3 id="How_does_Heroku_work">How does Heroku work?</h3>
+
+<p>Heroku runs Django websites within one or more "<a href="https://devcenter.heroku.com/articles/dynos">Dynos</a>", which are isolated, virtualized Unix containers that provide the environment required to run an application. The dynos are completely isolated and have an <em>ephemeral</em> file system (a short-lived file system that is cleaned/emptied every time the dyno restarts). The only thing that dynos share by default are application <a href="https://devcenter.heroku.com/articles/config-vars">configuration variables</a>. Heroku internally uses a load balancer to distribute web traffic to all "web" dynos. Since nothing is shared between them, Heroku can scale an app horizontally simply by adding more dynos (though of course you may also need to scale your database to accept additional connections).</p>
+
+<p>Because the file system is ephemeral you can't install services required by your application directly (e.g. databases, queues, caching systems, storage, email services, etc). Instead Heroku web applications use backing services provided as independent "add-ons" by Heroku or 3rd parties. Once attached to your web application, the dynos access the services using information contained in application configuration variables.</p>
+
+<p>In order to execute your application Heroku needs to be able to set up the appropriate environment and dependencies, and also understand how it is launched. For Django apps we provide this information in a number of text files:</p>
+
+<ul>
+ <li><strong>runtime.txt</strong>:<strong> </strong>the programming language and version to use.</li>
+ <li><strong>requirements.txt</strong>: the Python component dependencies, including Django.</li>
+ <li><strong>Procfile</strong>: A list of processes to be executed to start the web application. For Django this will usually be the Gunicorn web application server (with a <code>.wsgi</code> script).</li>
+ <li><strong>wsgi.py</strong>: <a href="http://wsgi.readthedocs.io/en/latest/what.html">WSGI</a> configuration to call our Django application in the Heroku environment.</li>
+</ul>
+
+<p>Developers interact with Heroku using a special client app/terminal, which is much like a Unix Bash shell. This allows you to upload code that is stored in a git repository, inspect the running processes, see logs, set configuration variables and much more!</p>
+
+<p>In order to get our application to work on Heroku we'll need to put our Django web application into a git repository, add the files above, integrate with a database add-on, and make changes to properly handle static files.</p>
+
+<p>Once we've done all that we can set up a Heroku account, get the Heroku client, and use it to install our website.</p>
+
+<div class="note">
+<p><strong>Note:</strong> The instructions below reflect how to work with Heroku at time of writing. If Heroku significantly change their processes, you may wish to instead check their setup documents: <a href="https://devcenter.heroku.com/articles/getting-started-with-python#introduction">Getting Started on Heroku with Django</a>.</p>
+</div>
+
+<p>That's all the overview you need in order to get started (see <a href="https://devcenter.heroku.com/articles/how-heroku-works">How Heroku works</a> for a more comprehensive guide).</p>
+
+<h3 id="Creating_an_application_repository_in_Github">Creating an application repository in Github</h3>
+
+<p>Heroku is closely integrated with the <strong>git</strong> source code version control system, using it to upload/synchronise any changes you make to the live system. It does this by adding a new heroku "remote" repository named <em>heroku</em> pointing to a repository for your source on the Heroku cloud. During development you use git to store changes on your "master" repository. When you want to deploy your site, you sync your changes to the Heroku repository.</p>
+
+<div class="note">
+<p><strong>Note:</strong> If you're used to following good software development practices you are probably already using git or some other SCM system. If you already have a git repository, then you can skip this step.</p>
+</div>
+
+<p>There are a lot of ways to work with git, but one of the easiest is to first set up an account on <a href="https://github.com/">Github</a>, create the repository there, and then sync to it locally:</p>
+
+<ol>
+ <li>Visit <a href="https://github.com/">https://github.com/</a> and create an account.</li>
+ <li>Once you are logged in, click the <strong>+</strong> link in the top toolbar and select <strong>New repository</strong>.</li>
+ <li>Fill in all the fields on this form. While these are not compulsory, they are strongly recommended.
+ <ul>
+ <li>Enter a new repository name (e.g. <em>django_local_library</em>), and description (e.g. "Local Library website written in Django".</li>
+ <li>Choose <strong>Python</strong> in the <em>Add .gitignore</em> selection list.</li>
+ <li>Choose your preferred license in the <em>Add license</em> selection list.</li>
+ <li>Check <strong>Initialize this repository with a README</strong>.</li>
+ </ul>
+ </li>
+ <li>Press <strong>Create repository</strong>.</li>
+ <li>Click the green "<strong>Clone or download</strong>" button on your new repo page.</li>
+ <li>Copy the URL value from the text field inside the dialog box that appears (it should be something like: <strong>https://github.com/<em>&lt;your_git_user_id&gt;</em>/django_local_library.git</strong>).</li>
+</ol>
+
+<p>Now that the repository ("repo") is created we are going to want to clone it on our local computer:</p>
+
+<ol>
+ <li>Install <em>git</em> for your local computer (you can find versions for different platforms <a href="https://git-scm.com/downloads">here</a>).</li>
+ <li>Open a command prompt/terminal and clone your repository using the URL you copied above:
+ <pre class="brush: bash notranslate">git clone https://github.com/<strong><em>&lt;your_git_user_id&gt;</em></strong>/django_local_library.git
+</pre>
+ This will create the repository in a new folder in the current working directory.</li>
+ <li>Navigate into the new repo.
+ <pre class="brush: bash notranslate">cd django_local_library</pre>
+ </li>
+</ol>
+
+<p>The final steps are to copy your application into this local project directory and then add (or "push", in git lingo) the local repository to your remote Github repository:</p>
+
+<ol>
+ <li>Copy your Django application into this folder (all the files at the same level as <strong>manage.py</strong> and below, <strong>not</strong> their containing locallibrary folder).</li>
+ <li>Open the <strong>.gitignore</strong> file, copy the following lines into the bottom of it, and then save (this file is used to identify files that should not be uploaded to git by default).
+ <pre class="notranslate"># Text backup files
+*.bak
+
+# Database
+*.sqlite3</pre>
+ </li>
+ <li>Open a command prompt/terminal and use the <code>add</code> command to add all files to git. This adds the files which aren't ignored by the <strong>.gitignore</strong> file to the "staging area".
+ <pre class="brush: bash notranslate">git add -A
+</pre>
+ </li>
+ <li>Use the <code>status</code> command to check that all files you are about to <code>commit</code> are correct (you want to include source files, not binaries, temporary files etc.). It should look a bit like the listing below.
+ <pre class="notranslate">&gt; git status
+On branch master
+Your branch is up-to-date with 'origin/master'.
+Changes to be committed:
+  (use "git reset HEAD &lt;file&gt;..." to unstage)
+
+        modified:   .gitignore
+        new file:   catalog/__init__.py
+ ...
+        new file:   catalog/migrations/0001_initial.py
+ ...
+        new file:   templates/registration/password_reset_form.html</pre>
+ </li>
+ <li>When you're satisfied, <code>commit</code> the files to your local repository. This is essentially equivalent to signing off on the changes and making them an official part of the local repository.
+ <pre class="brush: bash notranslate">git commit -m "First version of application moved into github"</pre>
+ </li>
+ <li>At this point, the remote repository has not been changed. Synchronise (<code>push</code>) your local repository to the remote Github repository using the following command:
+ <pre class="notranslate">git push origin master</pre>
+ </li>
+</ol>
+
+<p>When this operation completes, you should be able to go back to the page on Github where you created your repo, refresh the page, and see that your whole application has now been uploaded. You can continue to update your repository as files change using this add/commit/push cycle.</p>
+
+<div class="note">
+<p><strong>Tip:</strong> This is a good point to make a backup of your "vanilla" project — while some of the changes we're going to be making in the following sections might be useful for deployment on any platform (or development) others might not.</p>
+
+<p>The <em>best</em> way to do this is to use <em>git</em> to manage your revisions. With <em>git</em> you can not only go back to a particular old version, but you can maintain this in a separate "branch" from your production changes and cherry-pick any changes to move between production and development branches. <a href="https://help.github.com/articles/good-resources-for-learning-git-and-github/">Learning Git</a> is well worth the effort, but is beyond the scope of this topic.</p>
+
+<p>The <em>easiest</em> way to do this is to just copy your files into another location. Use whichever approach best matches your knowledge of git!</p>
+</div>
+
+<h3 id="Update_the_app_for_Heroku">Update the app for Heroku</h3>
+
+<p>This section explains the changes you'll need to make to our <em>LocalLibrary</em> application to get it to work on Heroku. While Heroku's <a href="https://devcenter.heroku.com/articles/getting-started-with-python#introduction">Getting Started on Heroku with Django</a> instructions assume you will use the Heroku client to also run your local development environment, our changes are compatible with the existing Django development server and the workflows we've already learned.</p>
+
+<h4 id="Procfile">Procfile</h4>
+
+<p>Create the file <code>Procfile</code> (no extension) in the root of your GitHub repository to declare the application's process types and entry points. Copy the following text into it:</p>
+
+<pre class="notranslate">web: gunicorn locallibrary.wsgi --log-file -</pre>
+
+<p>The "<code>web:</code>" tells Heroku that this is a web dyno and can be sent HTTP traffic. The process to start in this dyno is <em>gunicorn</em>, which is a popular web application server that Heroku recommends. We start Gunicorn using the configuration information in the module <code>locallibrary.wsgi</code> (created with our application skeleton: <strong>/locallibrary/wsgi.py</strong>).</p>
+
+<h4 id="Gunicorn">Gunicorn</h4>
+
+<p><a href="http://gunicorn.org/">Gunicorn</a> is the recommended HTTP server for use with Django on Heroku (as referenced in the Procfile above). It is a pure-Python HTTP server for WSGI applications that can run multiple Python concurrent processes within a single dyno (see <a href="https://devcenter.heroku.com/articles/python-gunicorn">Deploying Python applications with Gunicorn</a> for more information).</p>
+
+<p>While we won't need <em>Gunicorn</em> to serve our LocalLibrary application during development, we'll install it so that it becomes part of our <a href="#requirements">requirements</a> for Heroku to set up on the remote server.</p>
+
+<p>Install <em>Gunicorn</em> locally on the command line using <em>pip</em> (which we installed when <a href="/en-US/docs/Learn/Server-side/Django/development_environment">setting up the development environment</a>):</p>
+
+<div class="blockIndicator note">
+<p>Note: Make sure that you're in your Python virtual environment (use the <code>workon [name-of-virtual-environment]</code> command) before you install <em>Gunicorn</em> and further modules with <em>pip</em>, or you might experience problems with importing these modules in your <strong>/locallibrary/settings.py</strong> file in the later sections. </p>
+</div>
+
+<pre class="brush: bash notranslate">pip3 install gunicorn
+</pre>
+
+<h4 id="Database_configuration">Database configuration</h4>
+
+<p>We can't use the default SQLite database on Heroku because it is file-based, and it would be deleted from the <em>ephemeral</em> file system every time the application restarts (typically once a day, and every time the application or its configuration variables are changed).</p>
+
+<p>The Heroku mechanism for handling this situation is to use a <a href="https://elements.heroku.com/addons#data-stores">database add-on</a> and configure the web application using information from an environment <a href="https://devcenter.heroku.com/articles/config-vars">configuration variable</a>, set by the add-on. There are quite a lot of database options, but we'll use the <a href="https://devcenter.heroku.com/articles/heroku-postgres-plans#plan-tiers">hobby tier</a> of the <em>Heroku postgres</em> database as this is free, supported by Django, and automatically added to our new Heroku apps when using the free hobby dyno plan tier.</p>
+
+<p>The database connection information is supplied to the web dyno using a configuration variable named <code>DATABASE_URL</code>. Rather than hard-coding this information into Django, Heroku recommends that developers use the <a href="https://warehouse.python.org/project/dj-database-url/">dj-database-url</a> package to parse the <code>DATABASE_URL</code> environment variable and automatically convert it to Django’s desired configuration format. In addition to installing the <em>dj-database-url</em> package we'll also need to install <a href="http://initd.org/psycopg/">psycopg2</a>, as Django needs this to interact with Postgres databases.</p>
+
+<h5 id="dj-database-url_Django_database_configuration_from_environment_variable">dj-database-url (Django database configuration from environment variable)</h5>
+
+<p>Install <em>dj-database-url</em> locally so that it becomes part of our <a href="#requirements">requirements</a> for Heroku to set up on the remote server:</p>
+
+<pre class="notranslate">$ pip3 install dj-database-url
+</pre>
+
+<h5 id="settings.py">settings.py</h5>
+
+<p>Open <strong>/locallibrary/settings.py</strong> and copy the following configuration into the bottom of the file:</p>
+
+<pre class="notranslate"># Heroku: Update database configuration from $DATABASE_URL.
+import dj_database_url
+db_from_env = dj_database_url.config(conn_max_age=500)
+DATABASES['default'].update(db_from_env)</pre>
+
+<div class="note">
+<p><strong>Note:</strong></p>
+
+<ul>
+ <li>We'll still be using SQLite during development because the <code>DATABASE_URL</code> environment variable will not be set on our development computer.</li>
+ <li>The value <code>conn_max_age=500</code> makes the connection persistent, which is far more efficient than recreating the connection on every request cycle. However, this is optional and can be removed if needed.</li>
+</ul>
+</div>
+
+<h5 id="psycopg2_Python_Postgres_database_support">psycopg2 (Python Postgres database support)</h5>
+
+<p>Django needs <em>psycopg2</em> to work with Postgres databases and you will need to add this to the <a href="#requirements">requirements.txt</a> for Heroku to set this up on the remote server (as discussed in the requirements section below).</p>
+
+<p>Django will use our SQLite database locally by default, because the <code>DATABASE_URL</code> environment variable isn't set in our local environment. If you want to switch to Postgres completely and use our Heroku free tier database for both development and production then you can. For example, to install psycopg2 and its dependencies locally on a Debian-flavoured Linux system you would use the following Bash/terminal commands:</p>
+
+<pre class="brush: bash notranslate"><code>sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib</code>
+pip3 install psycopg2-binary
+</pre>
+
+<p>Installation instructions for the other platforms can be found on the <a href="http://initd.org/psycopg/docs/install.html">psycopg2 website here</a>.</p>
+
+<p>However, you don't need to do this — you don't need PostgreSQL active on the local computer, as long as you give it to Heroku as a requirement, in <code>requirements.txt</code> (see below).</p>
+
+<h4 id="Serving_static_files_in_production">Serving static files in production</h4>
+
+<p>During development we used Django and the Django development web server to serve our static files (CSS, JavaScript, etc.). In a production environment we instead typically serve static files from a content delivery network (CDN) or the web server.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Serving static files via Django/web application is inefficient because the requests have to pass through unnecessary additional code (Django) rather than being handled directly by the web server or a completely separate CDN. While this doesn't matter for local use during development, it would have a significant performance impact if we were to use the same approach in production. </p>
+</div>
+
+<p>To make it easy to host static files separately from the Django web application, Django provides the <em>collectstatic</em> tool to collect these files for deployment (there is a settings variable that defines where the files should be collected when <em>collectstatic</em> is run). Django templates refer to the hosting location of the static files relative to a settings variable (<code>STATIC_URL</code>), so that this can be changed if the static files are moved to another host/server.</p>
+
+<p>The relevant setting variables are:</p>
+
+<ul>
+ <li><code>STATIC_URL</code>: This is the base URL location from which static files will be served, for example on a CDN. This is used for the static template variable that is accessed in our base template (see <a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a>).</li>
+ <li><code>STATIC_ROOT</code>: This is the absolute path to a directory where Django's "collectstatic" tool will gather any static files referenced in our templates. Once collected, these can then be uploaded as a group to wherever the files are to be hosted.</li>
+ <li><code>STATICFILES_DIRS</code>: This lists additional directories that Django's collectstatic tool should search for static files.</li>
+</ul>
+
+<h5 id="settings.py_2">settings.py</h5>
+
+<p>Open <strong>/locallibrary/settings.py</strong> and copy the following configuration into the bottom of the file. The <code>BASE_DIR</code> should already have been defined in your file (the <code>STATIC_URL</code> may already have been defined within the file when it was created. While it will cause no harm, you might as well delete the duplicate previous reference).</p>
+
+<pre class="notranslate"># Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/2.1/howto/static-files/
+
+# The absolute path to the directory where collectstatic will collect static files for deployment.
+STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
+
+# The URL to use when referring to static files (where they will be served from)
+STATIC_URL = '/static/'
+</pre>
+
+<p>We'll actually do the file serving using a library called <a href="https://warehouse.python.org/project/whitenoise/">WhiteNoise</a>, which we install and configure in the next section.</p>
+
+<p>For more information, see <a href="https://devcenter.heroku.com/articles/django-assets">Django and Static Assets</a> (Heroku docs).</p>
+
+<h4 id="Whitenoise">Whitenoise</h4>
+
+<p>There are many ways to serve static files in production (we saw the relevant Django settings in the previous sections). Heroku recommends using the <a href="https://warehouse.python.org/project/whitenoise/">WhiteNoise</a> project for serving of static assets directly from Gunicorn in production.</p>
+
+<div class="note">
+<p><strong>Note: </strong>Heroku automatically calls <em>collectstatic</em> and prepares your static files for use by WhiteNoise after it uploads your application. Check out <a href="https://warehouse.python.org/project/whitenoise/">WhiteNoise</a> documentation for an explanation of how it works and why the implementation is a relatively efficient method for serving these files.</p>
+</div>
+
+<p>The steps to set up <em>WhiteNoise</em> to use with the project are <a href="http://whitenoise.evans.io/en/stable/django.html">given here</a> (and reproduced below):</p>
+
+<h5 id="WhiteNoise">WhiteNoise</h5>
+
+<p>Install whitenoise locally using the following command:</p>
+
+<pre class="notranslate">$ pip3 install whitenoise
+</pre>
+
+<h5 id="settings.py_3">settings.py</h5>
+
+<p>To install <em>WhiteNoise</em> into your Django application, open <strong>/locallibrary/settings.py</strong>, find the <code>MIDDLEWARE</code> setting and add the <code>WhiteNoiseMiddleware</code> near the top of the list, just below the <code>SecurityMiddleware</code>:</p>
+
+<pre class="notranslate">MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+ <strong>'whitenoise.middleware.WhiteNoiseMiddleware',</strong>
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+</pre>
+
+<p>Optionally, you can reduce the size of the static files when they are served (this is more efficient). Just add the following to the bottom of <strong>/locallibrary/settings.py</strong>:</p>
+
+<pre class="notranslate"># Simplified static file serving.
+# https://warehouse.python.org/project/whitenoise/
+STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
+</pre>
+
+<h4 id="Requirements">Requirements</h4>
+
+<p>The Python requirements of your web application must be stored in a file <strong>requirements.txt</strong> in the root of your repository. Heroku will then install these automatically when it rebuilds your environment. You can create this file using <em>pip</em> on the command line (run the following in the repo root):</p>
+
+<pre class="brush: bash notranslate">pip3 freeze &gt; requirements.txt</pre>
+
+<p>After installing all the different dependencies above, your <strong>requirements.txt</strong> file should have <em>at least</em> these items listed (though the version numbers may be different). Please delete any other dependencies not listed below, unless you've explicitly added them for this application.</p>
+
+<pre class="notranslate">dj-database-url==0.5.0
+Django==2.1.5
+gunicorn==19.9.0
+<strong>psycopg2-binary==2.7.7</strong>
+whitenoise==4.1.2
+</pre>
+
+<div class="note">
+<p>Make sure that a <strong>psycopg2</strong> line like the one above is present! Even if you didn't install this locally then you should still add it to <strong>requirements.txt</strong>.</p>
+</div>
+
+<h4 id="Runtime">Runtime</h4>
+
+<p>The <strong>runtime.txt</strong> file, if defined, tells Heroku which programming language to use. Create the file in the root of the repo and add the following text:</p>
+
+<pre class="notranslate">python-3.7.0</pre>
+
+<div class="note">
+<p><strong>Note:</strong> Heroku only supports a small number of <a href="https://devcenter.heroku.com/articles/python-support#supported-python-runtimes">Python runtimes</a> (at time of writing, this includes the one above). Heroku will use a supported runtime irrespective of the value specified in this file.</p>
+</div>
+
+<h4 id="Re-test_and_save_changes_to_Github">Re-test and save changes to Github</h4>
+
+<p>Before we proceed, lets test the site again locally and make sure it wasn't broken by any of our changes above. Run the development web server as usual and then check the site still works as you expect on your browser.</p>
+
+<pre class="brush: bash notranslate">python3 manage.py runserver</pre>
+
+<p>Next, lets <code>push</code> our changes to Github. In the terminal (after having navigated to our local repository), enter the following commands:</p>
+
+<pre class="brush: python notranslate">git add -A
+git commit -m "Added files and changes required for deployment to heroku"
+git push origin master
+</pre>
+
+<p>We should now be ready to start deploying LocalLibrary on Heroku.</p>
+
+<h3 id="Get_a_Heroku_account">Get a Heroku account</h3>
+
+<p>To start using Heroku you will first need to create an account:</p>
+
+<ul>
+ <li>Go to <a href="https://www.heroku.com/">www.heroku.com</a> and click the <strong>SIGN UP FOR FREE</strong> button.</li>
+ <li>Enter your details and then press <strong>CREATE FREE ACCOUNT</strong>. You'll be asked to check your account for a sign-up email.</li>
+ <li>Click the account activation link in the signup email. You'll be taken back to your account on the web browser.</li>
+ <li>Enter your password and click <strong>SET PASSWORD AND LOGIN</strong>.</li>
+ <li>You'll then be logged in and taken to the Heroku dashboard: <a href="https://dashboard.heroku.com/apps">https://dashboard.heroku.com/apps</a>.</li>
+</ul>
+
+<h3 id="Install_the_client">Install the client</h3>
+
+<p>Download and install the Heroku client by following the <a href="https://devcenter.heroku.com/articles/getting-started-with-python#set-up">instructions on Heroku here</a>.</p>
+
+<p>After the client is installed you will be able run commands. For example to get help on the client:</p>
+
+<pre class="brush: bash notranslate">heroku help
+</pre>
+
+<h3 id="Create_and_upload_the_website">Create and upload the website</h3>
+
+<p>To create the app we run the "create" command in the root directory of our repository. This creates a git remote ("pointer to a remote repository") named <em>heroku</em> in our local git environment.</p>
+
+<pre class="brush: bash notranslate">heroku create</pre>
+
+<div class="note">
+<p><strong>Note:</strong> You can name the remote if you like by specifying a value after "create". If you don't then you'll get a random name. The name is used in the default URL.</p>
+</div>
+
+<p>We can then push our app to the Heroku repository as shown below. This will upload the app, package it in a dyno, run collectstatic, and start the site.</p>
+
+<pre class="brush: bash notranslate">git push heroku master</pre>
+
+<p>If we're lucky, the app is now "running" on the site, but it won't be working properly because we haven't set up the database tables for use by our application. To do this we need to use the <code>heroku run</code> command and start a "<a href="https://devcenter.heroku.com/articles/deploying-python#one-off-dynos">one off dyno</a>" to perform a migrate operation. Enter the following command in your terminal:</p>
+
+<pre class="brush: bash notranslate">heroku run python manage.py migrate</pre>
+
+<p>We're also going to need to be able to add books and authors, so lets also create our administration superuser, again using a one-off dyno:</p>
+
+<pre class="brush: bash notranslate">heroku run python manage.py createsuperuser</pre>
+
+<p>Once this is complete, we can look at the site. It should work, although it won't have any books in it yet. To open your browser to the new website, use the command:</p>
+
+<pre class="brush: bash notranslate">heroku open</pre>
+
+<p>Create some books in the admin site, and check out whether the site is behaving as you expect.</p>
+
+<h3 id="Managing_addons">Managing addons</h3>
+
+<p>You can check out the add-ons to your app using the <code>heroku addons</code> command. This will list all addons, and their price tier and state.</p>
+
+<pre class="brush: bash notranslate">&gt; heroku addons
+
+Add-on Plan Price State
+───────────────────────────────────────── ───────── ───── ───────
+heroku-postgresql (postgresql-flat-26536) hobby-dev free created
+ └─ as DATABASE</pre>
+
+<p>Here we see that we have just one add-on, the postgres SQL database. This is free, and was created automatically when we created the app. You can open a web page to examine the database add-on (or any other add-on) in more detail using the following command:</p>
+
+<pre class="brush: bash notranslate">heroku addons:open heroku-postgresql
+</pre>
+
+<p>Other commands allow you to create, destroy, upgrade and downgrade addons (using a similar syntax to opening). For more information see <a href="https://devcenter.heroku.com/articles/managing-add-ons">Managing Add-ons</a> (Heroku docs).</p>
+
+<h3 id="Setting_configuration_variables">Setting configuration variables</h3>
+
+<p>You can check out the configuration variables for the site using the <code>heroku config</code> command. Below you can see that we have just one variable, the <code>DATABASE_URL</code> used to configure our database.</p>
+
+<pre class="brush: bash notranslate">&gt; heroku config
+
+=== locallibrary Config Vars
+DATABASE_URL: postgres://uzfnbcyxidzgrl:j2jkUFDF6OGGqxkgg7Hk3ilbZI@ec2-54-243-201-144.compute-1.amazonaws.com:5432/dbftm4qgh3kda3</pre>
+
+<p>If you recall from the section on <a href="#Getting_your_website_ready_to_publish">getting the website ready to publish</a>, we have to set environment variables for <code>DJANGO_SECRET_KEY</code> and <code>DJANGO_DEBUG</code>. Let's do this now.</p>
+
+<div class="note">
+<p><strong>Note:</strong> The secret key needs to be really secret! One way to generate a new key is to use the <a href="https://www.miniwebtool.com/django-secret-key-generator/">Django Secret Key Generator</a>.</p>
+</div>
+
+<p>We set <code>DJANGO_SECRET_KEY</code> using the <code>config:set</code> command (as shown below). Remember to use your own secret key!</p>
+
+<pre class="brush: bash notranslate">&gt; heroku config:set DJANGO_SECRET_KEY='eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&amp;='
+
+Setting DJANGO_SECRET_KEY and restarting locallibrary... done, v7
+DJANGO_SECRET_KEY: eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh
+</pre>
+
+<p>We similarly set <code>DJANGO_DEBUG</code>:</p>
+
+<pre class="brush: bash notranslate">&gt; heroku config:set <code>DJANGO_DEBUG=
+
+Setting DJANGO_DEBUG and restarting locallibrary... done, v8</code></pre>
+
+<p>If you visit the site now you'll get a "Bad request" error, because the <a href="https://docs.djangoproject.com/en/2.1/ref/settings/#allowed-hosts">ALLOWED_HOSTS</a> setting is <em>required</em> if you have <code>DEBUG=False</code> (as a security measure). Open <strong>/locallibrary/settings.py</strong> and change the <code>ALLOWED_HOSTS</code> setting to include your base app url (e.g. 'locallibrary1234.herokuapp.com') and the URL you normally use on your local development server.</p>
+
+<pre class="brush: python notranslate">ALLOWED_HOSTS = ['&lt;your app URL without the https:// prefix&gt;.herokuapp.com','127.0.0.1']
+# For example:
+# ALLOWED_HOSTS = ['fathomless-scrubland-30645.herokuapp.com', '127.0.0.1']
+</pre>
+
+<p>Then save your settings and commit them to your Github repo and to Heroku:</p>
+
+<pre class="brush: bash notranslate">git add -A
+git commit -m 'Update ALLOWED_HOSTS with site and development server URL'
+git push origin master
+git push heroku master</pre>
+
+<div class="note">
+<p>After the site update to Heroku completes, enter a URL that does not exist (e.g. <strong>/catalog/doesnotexist/</strong>). Previously this would have displayed a detailed debug page, but now you should just see a simple "Not Found" page.</p>
+</div>
+
+<h3 id="Debugging">Debugging</h3>
+
+<p>The Heroku client provides a few tools for debugging:</p>
+
+<pre class="brush: bash notranslate"># Show current logs
+heroku logs
+
+# Show current logs and keep updating with any new results
+heroku logs --tail
+
+# Add additional logging for collectstatic (this tool is run automatically during a build)
+heroku config:set DEBUG_COLLECTSTATIC=1
+
+# Display dyno status
+heroku ps
+</pre>
+
+<p>If you need more information than these can provide you will need to start looking into <a href="https://docs.djangoproject.com/en/2.1/topics/logging/">Django Logging</a>.</p>
+
+<ul>
+</ul>
+
+<h2 id="Summary">Summary</h2>
+
+<p>That's the end of this tutorial on setting up Django apps in production, and also the series of tutorials on working with Django. We hope you've found them useful. You can check out a fully worked-through version of the <a href="https://github.com/mdn/django-locallibrary-tutorial">source code on Github here</a>.<br>
+ <br>
+ The next step is to read our last few articles, and then complete the assessment task.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/deployment/">Deploying Django</a> (Django docs)
+
+ <ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/">Deployment checklist</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/static-files/deployment/">Deploying static files</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/">How to deploy with WSGI</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/modwsgi/">How to use Django with Apache and mod_wsgi</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/gunicorn/">How to use Django with Gunicorn</a> (Django docs)</li>
+ </ul>
+ </li>
+ <li>Heroku
+ <ul>
+ <li><a href="https://devcenter.heroku.com/articles/django-app-configuration">Configuring Django apps for Heroku</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/getting-started-with-python#introduction">Getting Started on Heroku with Django</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/django-assets">Django and Static Assets</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/python-concurrency-and-database-connections">Concurrency and Database Connections in Django</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/how-heroku-works">How Heroku works</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/dynos">Dynos and the Dyno Manager</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/config-vars">Configuration and Config Vars</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/limits">Limits</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/python-gunicorn">Deploying Python applications with Gunicorn</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/articles/deploying-python">Deploying Python and Django apps on Heroku</a> (Heroku docs)</li>
+ <li><a href="https://devcenter.heroku.com/search?q=django">Other Heroku Django docs</a></li>
+ </ul>
+ </li>
+ <li>Digital Ocean
+ <ul>
+ <li><a href="https://www.digitalocean.com/community/tutorials/how-to-serve-django-applications-with-uwsgi-and-nginx-on-ubuntu-16-04">How To Serve Django Applications with uWSGI and Nginx on Ubuntu 16.04</a></li>
+ <li><a href="https://www.digitalocean.com/community/tutorials?q=django">Other Digital Ocean Django community docs</a></li>
+ </ul>
+ </li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/index.html b/files/pt-br/learn/server-side/django/index.html
new file mode 100644
index 0000000000..58d0f08a16
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/index.html
@@ -0,0 +1,75 @@
+---
+title: Django Web Framework (Python)
+slug: Learn/Server-side/Django
+tags:
+ - Aprender
+ - CodingScripting
+ - Desenvolvimento Web
+ - Iniciante
+ - Introdução
+ - Python
+ - django
+ - framework
+translation_of: Learn/Server-side/Django
+---
+<div>{{LearnSidebar}}</div>
+
+<p>Django é um framework de web server-side extremamente popular e repleto de características, escrito em Python. O módulo mostra por que o Django é um dos frameworks web mais populares, como configurar um ambiente de desenvolvimento e como começar a usa-lo para criar seus próprios aplicativos da Web.</p>
+
+<h2 id="Pré-requisitos">Pré-requisitos</h2>
+
+<p>Antes de iniciar este módulo você não precisa ter nenhum conhecimento de Django. Você precisará entender o que programação server-side e web frameworks são, idealmente lendo os tópicos em nosso módulo <a href="/pt-BR/docs/Learn/Server-side/First_steps">Server-side programação de website primeiros passos</a>.</p>
+
+<p>Um conhecimento geral de conceitos de programação e Python é recomendado, mas não essenciais para entendimento dos conceitos principais.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: O Python é uma das linguagens de programação mais fáceis para os iniciantes lerem e entenderem. Dito isto, se você quiser entender melhor este módulo, então existem inúmeros livros e tutoriais gratuitos disponíveis pela Internet (programadores iniciantes podem querer ver a página <a href="https://wiki.python.org/moin/BeginnersGuide/NonProgrammers">Python for não programadores</a> no wiki do python.org)</p>
+</div>
+
+<h2 id="Como_começar">Como começar?</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Introdu%C3%A7%C3%A3o">Introdução ao Django</a></dt>
+ <dd>
+ <p>Neste primeiro artigo sobre Django vamos responder a questão “O que é Django?” e mostrar um resumo sobre o que faz esse web framework ser especial. Nós vamos resumir os recursos principais, <span lang="pt-PT">i</span><span lang="pt-PT">ncluindo algumas das funcionalidades avançadas que não teremos tempo de detalhar neste módulo. Também mostraremos alguns dos principais blocos de construção de um aplicativo Django, para que você tenha uma idéia do que ele pode fazer antes de continuar e configurá-lo e começar a </span><span lang="pt-PT">se divertir</span><span lang="pt-PT">.</span></p>
+ </dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></dt>
+ <dd>Agora que você sabe para quê o Django serve, iremos mostrar-lhe como configurar e testar um ambiente de desenvolvimento Django no Windows, Linux (Ubuntu) e Mac OS X - ou qualquer outro sistema operacional que você esteja usando, esse artigo deve ajudá-lo no que precisa para começar a desenvolver aplicações no Django.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></dt>
+ <dd>O primeiro artigo em nossa série de tutoria prática explica o que você irá aprender, e provê uma visão geral do site de exemplo "biblioteca geral" que estaremos trabalhando e evoluindo nos artigos subsequentes.</dd>
+</dl>
+
+<dl>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></dt>
+ <dd>Esse artigo mostra como você pode criar um projeto de site "esqueleto" como base, o qual poderá ser preenchido com configurações, urls, models, views e templates de um site específico.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Utilizando models</a></dt>
+ <dd>Este artigo mostra como definir modelos para o site<em> </em><em>BibliotecaLocal</em> - os modelos representam <span id="result_box" lang="pt"><span>as estruturas de dados em que queremos armazenar os dados do aplicativo</span></span>, além de permitirem  o Django armazenar dados em banco de dados pela gente (e modificá-los depois). Ele explica o que é um modelo, como declará-lo, e alguns dos principais tipos de campos. Além de brevemente apresentar algumas das principais maneiras de acessar os dados de um modelo.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></dt>
+ <dd>Agora que nós criamos os modelos para o site <em>BibliotecaLocal, </em>iremos usar o site Django Admin para adicionar alguns dados "reais" de livros. Primeiros mostraremos como registrar os modelos com o site admin, e então veremos como fazer login e criar alguns dados. Ao final iremos mostrar algumas maneiras de aprimorar ainda mais a apresentação do site de administração.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></dt>
+ <dd>Agora estamos prontos para adicionar o código para exibir nossa primeira página inteira - uma home page para a BibliotecaLocal que mostra quantos registros temos de cada tipo de modelo e fornece links de navegação da barra lateral para nossas outras páginas. Ao longo do caminho, obteremos experiência prática ao escrever mapas e visualizações de URLs básicos, obtendo registros do banco de dados e usando modelos.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></dt>
+ <dd>Este tutorial estende nosso website <em>BibliotecaLocal</em> adicionando páginas de listagem e de detalhes, para livros e autores.  Aqui nós vamos aprender sobre visualizações genéricas baseadas em classes e mostrar como elas podem reduzir a quantidade de código que você tem que escrever para casos comuns.  Nós também entraremos na manipulação de URL em maiores detalhes, mostrando como realizar correspondências de padrões básicas.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></dt>
+ <dd>Este tutorial estende nosso site  <em>BibliotecaLocal</em>, adicionando um contador de visitas baseado em sessão  à home page. Esse é um exemplo relativamente simples, mas mostra como você pode usar a estrutura da sessão para prover um comportamento persistente para usuários anônimos em seus próprios sites.</dd>
+ <dt><a href="/pt-br/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: Autenticação de Usuário e permissões</a></dt>
+ <dd>Neste tutorial, mostraremos como permitir que os usuários façam login em seu site com suas próprias contas e como controlar o que podem fazer e ver com base no fato de estarem ou não logados e de suas permissões. Como parte dessa demonstração, ampliaremos o site da LocalLibrary, adicionando páginas de login e logout e páginas específicas de usuários e funcionários para a visualização de livros que foram emprestados.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></dt>
+ <dd>Neste tutorial iremos mostrar como trabalhar com <a href="/en-US/docs/Web/Guide/HTML/Forms">HTML Forms</a> no Django, e em particular a maneira mais fácil para escrever formulários para criar, atualizar e excluir instâncias do modelo. Como parte desta demonstração ampliaremos o website <em>BibliotecaLocal</em> para que bibliotecários possam renovar livros, e criar, atualizar e excluir autores usando usindo nossos próprios formulários (em vez de usar o aplicativo administrativo).</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></dt>
+ <dd>Conforme os sites crescem, tornam-se mais difíceis de testar manualmente - não apenas há mais para testar, mas à medida que as interações entre os componentes se tornam mais complexas, uma pequena alteração em uma área pode exigir muitos testes adicionais para verificar seu impacto em outras áreas. Uma forma de mitigar esses problemas é escrever testes automatizados, que podem ser executados de maneira fácil e confiável sempre que você fizer uma alteração. Este tutorial mostra como automatizar <em>o teste de unidade</em> do seu site usando a estrutura de teste do Django.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></dt>
+ <dd>Agora você criou (e testou) um site da LocalLibrary incrível, você vai querer instalá-lo em um servidor web público para que ele possa ser acessado pela equipe da biblioteca e membros pela Internet. Este artigo fornece uma visão geral de como você pode encontrar um host para implantar seu site e o que você precisa fazer para preparar seu site para a produção.</dd>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/web_application_security">Segurança de aplicações web Django</a></dt>
+ <dd>Proteger os dados do usuário é uma parte essencial do design de qualquer site. Anteriormente, explicamos algumas das ameaças de segurança mais comuns no artigo <a href="https://developer.mozilla.org/en-US/docs/Web/Security">Web security</a> - este artigo fornece uma demonstração prática de como as proteções internas do Django lidam com essas ameaças.</dd>
+ <dt></dt>
+</dl>
+
+<h2 id="Assessments">Assessments</h2>
+
+<p>A avaliação a seguir testará sua compreensão de como criar um site usando o Django, conforme descrito nos guias listados acima.</p>
+
+<dl>
+ <dt><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></dt>
+ <dd>Nesta avaliação, você usará alguns dos conhecimentos que aprendeu neste módulo para criar seu próprio blog.</dd>
+</dl>
diff --git a/files/pt-br/learn/server-side/django/introdução/index.html b/files/pt-br/learn/server-side/django/introdução/index.html
new file mode 100644
index 0000000000..9258d18dc6
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/introdução/index.html
@@ -0,0 +1,346 @@
+---
+title: Introdução ao Django
+slug: Learn/Server-side/Django/Introdução
+tags:
+ - Aprender
+ - Codificação
+ - Iniciante
+ - Introdução
+ - Programação do lado do servidor
+ - Python
+ - django
+translation_of: Learn/Server-side/Django/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Neste primeiro artigo do Django, respondemos a pergunta "O que é o Django?" e daremos uma visão geral do que torna este framework web especial. Vamos descrever os principais recursos, incluindo algumas das funcionalidades avançadas que não teremos tempo para abordar detalhadamente neste módulo. Também mostraremos alguns dos principais blocos de construção de um aplicativo Django (embora neste momento você ainda não tenha um ambiente de desenvolvimento para testá-lo).</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>
+ <p><span id="result_box" lang="pt"><span>Conhecimentos básicos em computação.</span> <span>Um entendimento geral de <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps">programação de websites do lado do servidor</a> e, em particular, a mecânica de <a href="/pt-BR/docs/">interações cliente-servidor em websites</a>.</span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivos:</th>
+ <td>Ganhar familiaridade com o que é o Django, quais funcionalidades ele fornece e os principais blocos de construção de uma aplicação django.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="O_que_é_Django">O que é Django?</h2>
+
+<p>Django é um framework web Python de alto nível que permite o rápido desenvolvimento de sites seguros e de fácil manutenção. Construido por desenvolvedores experientes, o Django cuida de grande parte do trabalho de desenvolvimento web, para que você possa se concentrar em escrever seu aplicativo sem precisar reinventar a roda. É gratuito e de código aberto, tem uma comunidade próspera e ativa, ótima documentação e muitas opções de suporte gratuito e pago. </p>
+
+<p>Django ajuda você a escrever programas que são:</p>
+
+<dl>
+ <dt>Completo</dt>
+ <dd>Django segue a filosofia de "baterias incluídas" e fornece quase tudo que desenvolvedores possam querer fazer "fora da caixa". Como tudo o que você precisa é parte de um "produto", tudo funciona perfeitamente junto, seguindo princípios de design consistentes, contando uma extensa e <a href="https://docs.djangoproject.com/pt-br/2.1/">atualizada documentação</a>.</dd>
+ <dt>Versátil</dt>
+ <dd>Django pode ser (e tem sido) utilizado para construir quase todo tipo de website - desde sistema de gestão de conteúdo e wikis, passando por redes sociais e sites de notícias. Ele pode trabalhar com qualquer framework do lado do cliente, e pode entregar conteúdo em praticamente qualquer formato (incluindo HTML, feeds RSS, JSON, XML, etc). Esse site que você está lendo agora é baseado em Django.</dd>
+ <dd>À medida em que, internamente, fornece opções para quase todo tipo de funcionalidade que você possa querer (por exemplo: vários banco de dados que são populares, motores de template, etc), ele pode também ser extendido para utilizar outros componentes, caso seja necessário.</dd>
+ <dt>Seguro</dt>
+ <dd>Django ajuda os desenvolvedores a evitar os erros de segurança mais comuns, fornecendo um framework que foi desenhado para "fazer as coisas certas", de modo a proteger o website automaticamente. Por exemplo, Django fornece uma maneira segura de gerenciar as contas dos usuários e suas senhas, evitando erros comuns, tais como colocar informações da sessão em cookies, onde ficam vulneráveis (ao invés disso os cookies contém apenas uma chave e os dados são armazenados no banco de dados), ou armazenar as senhas de forma direta, ao invés de gravar um hash para essas senhas.</dd>
+ <dd><em>Um hash de senha é um valor fixed-length (tamanho-fixo) criado mandando a senha por uma <a href="https://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_hash_criptogr%C3%A1fica">cryptographic hash function (função hash criptográfica)</a>. Django pode checar se uma senha inserida está correta executando ela pela função hash e comparando a saída com o valor hash armazenado. Porém devido a natureza "one-way" ("um-caminho") da função, mesmo que o valor hash armazenado estiver comprometido, é difcil para uma pessoa comentendo um ataque resolver a senha original.</em></dd>
+ <dd>O Django ativa a proteção contra muitas vulnerabilidades por padrão, incluindo SQL injection (injeção de SQL), cross-site scripting, cross-site request forgery (Falsificação de solicitação entre sites), e clickjacking ("furto de click") (veja <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Website_security">Segurança de sites</a> para mais detalhes de tais ataques).</dd>
+ <dt>Escalável</dt>
+ <dd>Django usa uma arquitetura baseada em componentes “<a href="https://en.wikipedia.org/wiki/Shared_nothing_architecture">shared-nothing</a>” ("nada-compartilhado") (cada parte da arquitetura é idependente das outras, e consequentemente podem ser subistituidas ou mudadas caso necessário). Ter uma separação clara entre as partes diferentes significa que pode se escalar para um trágefo aumentado adicionando hardware em qualquer nível: servidores de cache, servidores de banco de dados ou servidores de aplicação. Alguns dos sites mais ocupados escalaram o Django com sucesso para cumprir com as suas demandas (ex: Instagram e Disqus).</dd>
+ <dt>Sustentável</dt>
+ <dd>O código do Django é escrito usando princípios de design e padrões que encorajam a criação de codigo sustentável (que facilita a manutenção) e reusável. Em particular, isso utiliza o principio  DRY - Don't Repeat Yourself (Não Repita a Si Mesmo) para que não haja duplicações desnecessárias, reduzindo a quantidade de código. O Django também promove o agrupamento de funcionalidades relacionadas para aplicativos reusáveis e, em um nível mais baixo, grupos de código relacionados para modulos (juntamente as linhas do padrão <a href="https://pt.wikipedia.org/wiki/MVC">MVC - Model View Controller</a>).</dd>
+ <dt>Portável</dt>
+ <dd>Django é escrito em Python, que executa em muitas plataformas. Isso significa que você não esta preso em nenhuma plataforma de servidor em particular, e pode executar seus aplicativos em muitas distrubuições do Linux, Windows e Mac OS X. Além disso, o Django tem um bom suporte em muitos provedores de servidores de web, que muitas vezes provem infraestrutura especifca e documentação para hospedar sites feitos com Django.</dd>
+</dl>
+
+<h2 id="De_onde_o_Django_veio">De onde o Django veio?</h2>
+
+<p>Django foi inicialmente desenvolvido entre 2003 e 2005 por um time de web que era responsável por criar e manter sites de jornal. Depois de criar um número de sites, o time começou a fatorar e reutilizar muitos de seus códigos comuns e padrões de design. Esse código comum evoluiu para um framework genérico de desenvolvimento web, que foi lançado como um projeto de código aberto nomeado "Django" em Julho de 2005.</p>
+
+<p>Django continou a crescer e aprimorar, desde seu lançamento (1.0) em Setembro de 2008 até a versão recentemente lançada 2.0 em 2017. Cada lançamento adicionou novas funcionalidades e consertou falhas, variando entre suportar novos tipos de banco de dados, mecanismos de template e caches, até a adição de funções view "genéricas" e classes (que reduzem a quantidade de código que os desenvolvedores tem que escrever para um número de tarefas de programação).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Cheque as <span style="line-height: 1.5;"><a href="https://docs.djangoproject.com/pt-br/2.1/releases/">notas de lançamento</a> no site do Django para ver o que mudou nas versões mais recentes, e quanto trabalho esta sendo feito para tornar o Django melhor.</span></p>
+</div>
+
+<p>Django é um projeto de código aberto, colaborativo e próspero, com milhares de usuários contribuindo. Embora ainda tenha alguns recursos que refletem sua origem, Django evoluiu para um framework versátil que é capaz de desenvovler qualquer tipo de website.</p>
+
+<h2 id="Quão_popular_é_o_Django">Quão popular é o Django?</h2>
+
+<p>Não há nenhum método disponível e definitivo para medir a popularidade dos framework server-side (lado do servidor) (apesar de sites como <a href="http://hotframeworks.com/">Hot Frameworks</a> tentam acessar a popularidade usando mecanismos como contar o numero de projetos no GitHub e perguntas no StackOverflow para cada cada platafroma). Uma questão melhor é se o Django é "popular o suficiente" para evitar problemas de plataformas não populares. Ele continua a evoluir? Você consegue ajuda se precisar? Existem oportunidades para você ganhar dinheiro se voce aprender Django?</p>
+
+<p>Baseado no número de sites com alto perfil que usam Django, o número de pessoas contribuindo para a base de código, e o número de pessoas provendo ambos suporte gratuito e pago, então sim, Django é um framework popular!</p>
+
+<p>Alguns sites de alto perfil que usam Django são: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, and Open Stack (fonte: <a href="https://www.djangoproject.com/">Página inicial do django</a>).</p>
+
+<h2 id="O_Django_é_opinativo">O Django é opinativo?</h2>
+
+<p>Frameworks de web frequentemente referem a si mesmos como "opinativo" e "não opinativo".</p>
+
+<p>Frameworks opinativos são aqueles com opiniões sobre o "modo correto" de como lidar com uma tarefa em particular. Eles frequentemente auxiliam no desenvolvimento rapido <em>em um domínio em particular</em> (resolvendo problemas de um tipo em particular) porque o modo correto de fazer qualquer coisa normalmente já foi bem compreendido e bem documentado. Porém eles podem ser menos flexíveis para resolver problemas fora de seu principal domínio, e tendem a oferecer menos opções para quais componentes e abordagens eles podem usar.</p>
+
+<p>Frameworks não opinativos, em contraste, possuem bem menos restrições sobre a melhor maneira de unir os componentes para atingir um objetivo, ou até mesmo quais componentes devem ser usados. Eles tornam mais fácil para os desenvolvedores usar as ferramentas mais adequadas para completar uma tarefa em particular, apesar do custo de você mesmo ter que achar esses componentes.<br>
+ <br>
+ Django é "moderadamente opinativo" e, portantanto, oferece o "melhor dos dois mundo". Ele fornece um conjunto de componentes para lidar com a maioria das tarefas de desenvolvimento web, e uma (ou duas) maneiras preferidas de usá-las. No entanto, a arquitetura desacoplada do Django significa que você geralmente pode escolher entre várias opções diferentes, ou adicionar suporte para outras completamente novas, se desejar.</p>
+
+<h2 id="Com_o_que_o_código_do_Django_parece">Com o que o código do Django parece?</h2>
+
+<p>Em um site data-driven (orientado a dados) tradicional, um aplicativo web aguarda solicitações HTTP do navegador da web (ou outro cliente). Quando uma solicitação é recebida, o aplicativo calcula o que é necessário com base na URL e possivelmente nas informações dos dados <code>POST</code> ou <code>GET</code>. Dependendo do que for necessário, ele poderá ler ou gravar informações de um banco de dados ou executar outras tarefas necessárias para satisfazer a solicitação. O aplicativo retornará uma resposta para o navegador da web, normalmente criando dinamicamente uma página HTML para o navegador exibir, inserindo os dados recuperados em espaços reservados em um template HTML.</p>
+
+<p>Aplicativos web feitos com Django geralmente agrupam o código que manipula cada uma dessas etapas em arquivos separados:</p>
+
+<p><img alt="" src="https://i.postimg.cc/W4yzpVcd/arq.png" style="border-style: solid; border-width: 1px; height: 503px; width: 713px;"></p>
+
+<ul>
+ <li><strong>URLs: </strong>Embora seja possível processar solicitações de cada URL por meio de uma única função, é muito mais simples fazer a manutenção do código escrevendo uma função view (vista) separada para manipular cada recurso. Um mapeador de URLs é usado para redirecionar solicitações HTTP para a view apropriada com base na URL da solicitação. O mapeador de URLs também pode corresponder padrões específicos de strings (cadeia de caracteres) ou dígitos que aparecem em um URL e transmiti-los a uma função view como dados.</li>
+ <li><strong>View (Vista):</strong> Uma view é uma função manipuladora de solicitações, que recebe solicitações HTTP e retorna respostas HTTP. As views acessam os dados necessários para satisfazer solicitações por meio dos <em>models (modelos)</em> e encarregam a formatação da resposta aos <em>templates</em>.</li>
+ <li><strong>Models (Modelos):</strong> Modelos são objetos em Python que definem a estrutura dos dados de um aplicativo, e fornecem mecanismos para gerenciar (adicionar, modificar e excluir) e consultar registros no banco de dados.</li>
+ <li><strong>Templates:</strong> Um template é um arquivo de texto que define a estrutura ou o layout de um arquivo (como uma página HTML), com espaços reservados usados para representar o conteúdo real. Uma <em>view</em> pode criar dinamicamente uma página HTML usando um template HTML, preenchendo-a com dados de um <em>model (modelo)</em>. Um template pode ser usado para definir a estrutura de qualquer tipo de arquivo; não precisa ser HTML!</li>
+</ul>
+
+<div class="note">
+<p><strong>Nota</strong>: Django refere a essa organização como uma arquitetura nomeada "Model View Template (MVT)" ("Modelo Vista Template"). Ela tem muitas semelhanças com a familiar arquitetura <a href="https://pt.wikipedia.org/wiki/MVC">Model View Controller (Modelo Vista Controlador)</a>.</p>
+</div>
+
+<ul>
+</ul>
+
+<p>As seções abaixo lhe darão uma idéia de como essas partes principais de um aplicativo do Django se parecerão (nos vamos entrar em mais detalhes mais tarde no curso, assim que configurarmos um ambiente de desenvolvimento).</p>
+
+<h3 id="Enviando_a_solicitação_para_a_view_correta_urls.py">Enviando a solicitação para a view correta (urls.py)</h3>
+
+<p>Um mapeador de URLs normalmente é armazenado em um arquivo chamado <strong>urls.py</strong>. No exemplo abaixo, o mapeador (<code>urlpatterns</code>) (<em>padrões de url</em>) define uma lista de mapeamentos entre <em>rotas</em> (<em>padrões</em> específicos de URL) e funções view correspondentes. Se uma solicitação HTTP for recebida com uma URL correspondente a um padrão especificado, a função view associada será chamada e a solicitação/requisição sera transmitida.</p>
+
+<pre class="notranslate"><code>urlpatterns = [
+ <strong>path('admin/', admin.site.urls),</strong>
+ path('book/&lt;int:id&gt;/', views.book-detail, name='book-detail'),
+ path('catalog/', include('catalog.urls')),
+ re_path(r'^([0-9]+)/$', views.best),
+]
+
+# favor utilizar o código acima no seu projeto ao invés do que está abaixo
+# urlpatterns = [
+# path('admin/', admin.site.urls),
+# path('livro/&lt;int:id&gt;/', views.livro-detalhes, name='livro-detalhes'),
+# path('catalogo/', include('catalogo.urls')),
+#   re_path(r'^([0-9]+)/$', views.melhor),
+# ]</code>
+</pre>
+
+<p>O objeto <code>urlpatterns</code> é uma lista de funções <code>path()</code> (caminhos) e/ou <code>re_path()</code> (listas em Python são definidas usando colchetes, onde os itens são separados por vírgulas e podem conter opcionalmente uma vírgula no final. Por exemplo: <strong><code>[item1, item2, item3,]</code></strong>).</p>
+
+<p>O primeiro argumento para ambos os métodos é uma rota (padrão) que será correspondida. O método <code>path()</code> usa sinais de menor e maior (&lt;, &gt;) para definir partes de uma URL que serão capturadas e passadas para a função view como argumentos nomeados. A função <code>re_path()</code> usa uma abordagem de correspondência de padrões flexível, conhecida como expressão regular. Nós vamos falar sobre isso em um artigo posterior!</p>
+
+<p>O segundo argumento é outra função que será chamada quando o padrão for correspondido. A notação <code>views.book-detail</code> (<code>views.livro-detalhes</code>) indica que a função é chamada de <code>book-detail()</code> (<code>livro-detalhes()</code>) e pode ser encontrada em um módulo chamado <code>views</code> (ou seja, dentro de um arquivo chamado <code>views.py</code>)</p>
+
+<h3 id="Manipulando_a_solicitação_views.py">Manipulando a solicitação (views.py)</h3>
+
+<p>As view são o coração do aplicativo web, recebendo solicitações HTTP de clientes da web e retornando respostas HTTP. No meio disto, eles preparam os outros recursos do framework para acessar bancos de dados, renderizar (exibir) templates, etc.</p>
+
+<p>O exemplo abaixo mostra uma função view mínima chamada <code>index()</code>, que poderia ter sido chamado pelo nosso mapeador de URLs na seção anterior. Como todas as funções <em>view</em>, ele recebe um objeto <code>HttpRequest</code> como um parâmetro (<code>request</code>) e retorna um objeto <code>HttpResponse</code>. Nesse caso, não fazemos nada com a solicitação, e nossa resposta simplesmente retorna uma string. Mostraremos uma solicitação que faz algo mais interessante em uma seção posterior.</p>
+
+<pre class="brush: python notranslate">## filename: views.py (Django view functions)
+
+from django.http import HttpResponse
+
+def index(request):
+ # Get an HttpRequest - the request parameter
+ # perform operations using information from the request.
+  # Return HttpResponse
+ return HttpResponse('Hello from Django!')
+
+<code># favor utilizar o código acima no seu projeto ao invés do que está abaixo</code>
+## nome do arquivo: views.py (Onde as funções view ficam)
+
+from django.http import HttpResponse
+
+def index(requisito):
+ # Recebe um HttpRequest - o parametro requisito
+ # Executar operações usando informações do requisito (solicitação).
+ # Retornar HttpResponse
+ return HttpResponse('Um oi do Django!')
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Um pouquinho de Python:</p>
+
+<ul>
+ <li><a href="https://docs.python.org/3/tutorial/modules.html">Módulos do Python</a> são "bibliotecas" de funções, armazenadas em arquivos separados, que podemos utilizar em nosso código. Aqui nós importamos apenas o objeto <code>HttpResponse</code> do módulo <code>django.http</code> para que possamos usá-lo em nossa view: <code>from django.http import HttpResponse</code>. Existem outras maneiras de importar alguns ou todos os objetos de um módulo.</li>
+ <li>As funções em Python são declaradas usando a palavra-chave <code>def</code> como mostrado acima, com parâmetros nomeados listados entre parênteses após o nome da função; a linha inteira termina em dois pontos. Observe como as próximas linhas são todas <strong>recuadas</strong>. O recuo é importante, pois especifica que as linhas de código estão dentro desse bloco específico (a indentação obrigatória é um recurso chave do Python e é um dos motivos pelos quais o código Python é tão fácil de ler).</li>
+</ul>
+</div>
+
+<ul>
+</ul>
+
+<p>Views geralmente são armazenadas em um arquivo chamado <strong>views.py</strong>.</p>
+
+<h3 id="Definindo_o_modelo_dos_dados_models.py">Definindo o modelo dos dados (models.py)</h3>
+
+<p>Os aplicativos web feitos com Django gerenciam e consultam dados por meio de objetos do Python chamados de modelos. Os modelos definem a estrutura dos dados armazenados, incluindo os <em>tipos </em>do campo e possivelmente também seu tamanho máximo, valores padrão, opções de lista de seleção, texto de ajuda para documentação, texto de etiqueta (label) para formulários etc. A definição do modelo é independente do banco de dados subjacente — você pode escolher um dentre vários como parte das configurações do seu projeto. Uma vez que você escolheu qual banco de dados você quer usar, você não precisa se comunicar diretamente com ele — você apenas escreve a estrutura dos seus modelos e qualquer outro código, e o Django lida com todo o trabalho de se comunicar com o banco de dados para você.</p>
+
+<p>O trecho de código abaixo mostra um modelo simples do Django para um objeto <code>Team</code> (Time). A classe <code>Team</code> é derivada da classe do Django <code>models.Model</code>. Ela define o nome e o nível da equipe como campos de caractere e especifica um número máximo de caracteres a serem armazenados para cada registro. O <code>team_level</code> (time_nivel) pode ser um de vários valores, portanto, o definimos como um campo de opção e fornecemos um mapeamento entre as opções a serem exibidas e os dados a serem armazenados, junto com um valor padrão.</p>
+
+<pre class="brush: python notranslate">## filename: models.py
+
+from django.db import models
+
+class Team(models.Model):
+  team_name = models.CharField(max_length=40)
+
+    TEAM_LEVELS = (
+        ('U09', 'Under 09s'),
+        ('U10', 'Under 10s'),
+        ('U11', 'Under 11s'),
+  ... #list other team levels
+    )
+
+ team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
+
+<code># favor utilizar o código acima no seu projeto ao invés do que está abaixo</code>
+## nome do arquivo: models.py
+
+from django.db import models
+
+class Time(models.Model):
+ # models.CharField define um campo de caractere no banco de dados e max_length define o tamanho maximo permitido
+ time_nome = models.CharField(max_length=40)
+
+    TIME_NIVEIS = (
+        ('A09', 'Abaixo de 09'),
+        ('A10', 'Abaixo de 10'),
+       ('A11', 'Abaixo de 11'),
+   ... #list other team levels
+    )
+
+    time_nivel = models.CharField(max_length=3,choices=TIME_NIVEIS,default='A11') # choices-opções / default-padrão
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Um pouquinho de Python:</p>
+
+<ul>
+ <li>O Python suporta "programação orientada a objetos", um estilo de programação onde organizamos nosso código em objetos, que incluem dados e funções relacionadas para operar nesses dados. Os objetos também podem herdar/estender/derivar de outros objetos, permitindo que um comportamento comum entre objetos relacionados seja compartilhado. Em Python, usamos a palavra-chave <code>class</code> (classe) para definir o "blueprint" (modelo/planta/plano) de um objeto. Podemos criar várias <em>instâncias</em> específicas do tipo de objeto com base no modelo da classe.<br>
+ <br>
+ Por exemplo, aqui temos uma classe <code>Team</code> (Time), que deriva da classe <code>Model</code>. Isso significa que é um modelo e conterá todos os métodos de um modelo, mas também podemos fornecer recursos especializados próprios. Em nosso modelo, definimos os campos que nosso banco de dados precisará para armazenar nossos dados, dando-lhes nomes específicos. O Django usa essas definições, incluindo os nomes dos campos, para criar o banco de dados subjacente.</li>
+</ul>
+</div>
+
+<h3 id="Consultando_dados_views.py">Consultando dados (views.py)</h3>
+
+<p>O modelo Django fornece uma query API simples para buscas no banco de dados. Isto pode combinar com um grande número de campos ao mesmo tempo utilizando diversos critérios (ex.: exato, maiúsculas e minúsculas (case-sensitive), maior que, etc.), e pode suportar definições complexas (por exemplo, você pode especificar a busca por times U11 que tem os nomes começando com 'Fr" ou terminando com "al").</p>
+
+<p>O trecho de código mostra uma função da View (manipulador de recursos) para exibir todos os nossos times U09. A linha em negrito mostra como podemos usar a API modelo de consulta para filtrar todos os registros em que o campo <code>team_level</code> possui exatamente o texto 'U09' (observe como esse critério é passado para a função  <code>filter()</code>  com o argumento no campo de nome e o tipo de busca de correspondência (<strong>exact</strong>) separado por um sublinhado duplo: <strong>(team_level__exact</strong>).</p>
+
+<pre class="brush: python notranslate">## filename: views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def index(request):
+    <strong>list_teams = Team.objects.filter(team_level__exact="U09")</strong>
+    context = {'youngest_teams': list_teams}
+    return render(request, '/best/index.html', context)
+
+# favor utilizar o código acima no seu projeto ao invés do código abaixo
+## nome do arquivo: views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def index(request):
+ <strong>lista_times =</strong> <strong>Team.objects.filter(team_level__exact="U09")</strong>
+ contexto = {'times_jovens': lista_times}
+ return render(request, '/best/index.html', contexto)
+</pre>
+
+<dl>
+</dl>
+
+<p>A função <code>index()</code> usa a função <code>render()</code> para criar o <code>HttpResponse</code> que é enviado de volta para o navegador. Essa função é um atalho, ela cria um arquivo HTML combinando um modelo HTML específico com alguns dados (fornecidos pela variável denominada "<code>context</code>"). Na próxima seção, mostramos como os dados são inseridos no modelo para criar HTML.</p>
+
+<h3 id="Renderizando_dados_Modelos_HTML">Renderizando dados (Modelos HTML)</h3>
+
+<p>O sistema de modelo permite especificar a estrutura de um documento de saída, usando espaços reservados para dados que serão preenchidos quando uma página for gerada. Os modelos geralmente são usados para criar HTML, mas também podem criar outros tipos de documentos. O Django suporta o sistema de modelos nativo e outra biblioteca Python popular chamada Jinja2 pronta para uso (também pode ser feita para suportar outros sistemas, se necessário).</p>
+
+<p>O trecho de código mostra a aparência do modelo HTML chamado pela função <code>render()</code> na seção anterior. Este modelo foi escrito sob a premissa de que ele terá acesso a uma variável do tipo lista chamada <code>youngest_teams</code> quando for renderizada (contida na variável <code>context</code> dentro da função <code>render()</code> acima). Dentro do esqueleto HTML, temos um a expressão que primeiro verifica se a variável <code>youngest_teams</code> existe e a itera em um loop <code>for</code>. Em cada iteração, o modelo exibe o valor <code>team_name</code> de cada equipe em um elemento {{htmlelement("li")}}.</p>
+
+<pre class="brush: python notranslate">## filename: best/templates/best/index.html
+
+&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+&lt;body&gt;
+
+ {% if youngest_teams %}
+    &lt;ul&gt;
+    {% for team in youngest_teams %}
+        &lt;li&gt;\{\{ team.team_name \}\}&lt;/li&gt;
+    {% endfor %}
+    &lt;/ul&gt;
+{% else %}
+    &lt;p&gt;No teams are available.&lt;/p&gt;
+{% endif %}
+
+&lt;/body&gt;
+&lt;/html&gt;
+
+#favor utilizar o código acima no seu projeto ao invés do código abaixo
+## nome do arquivo: best/templates/best/index.html
+
+&lt;!DOCTYPE html&gt;
+&lt;html lang="pt"&gt;
+&lt;body&gt;
+
+ {% if youngest_teams %}
+ &lt;ul&gt;
+ {% for team in youngest_teams %}
+         &lt;li&gt;\{\{ team.team_name \}\}&lt;/li&gt;
+     {% endfor %}     &lt;/ul&gt; {% else %}
+     &lt;p&gt;Nenhum time disponível.&lt;/p&gt;
+ {% endif %}
+ &lt;/body&gt;
+ &lt;/html&gt;
+</pre>
+
+<h2 id="O_que_mais_você_pode_fazer">O que mais você pode fazer?</h2>
+
+<p>As seções anteriores mostram os principais recursos que você usará na maioria dos aplicativos Web: mapeamento de URL, views, moldes e modelos. O Django também fornece outras coisas, como:</p>
+
+<ul>
+ <li><strong>Formulários (Forms)</strong>: Os formulários HTML são usados para coletar dados do usuário para processamento no servidor. Django simplifica a criação, validação e processamento de formulários.</li>
+ <li><strong>Autenticação de usuário e permissões</strong>: Django inclui um sistema robusto de autenticção e permissão de usuário, construído com a segurança em mente.</li>
+ <li><strong>Caching</strong>: Criar conteúdo dinamicamente é muito mais pesado (e lento) computacionalmente do que exibir conteúdo estático. O Django fornece armazenamento em cache flexível para que você possa armazenar toda ou parte de uma página pronta para que ela não seja renderizada novamente, exceto quando necessário.</li>
+ <li><strong>Site de administração</strong>: O site de administração do Django é incluído por padrão quando você cria um aplicativo usando o esqueleto básico. Ele facilita o fornecimento de uma página de administração para os administradores do site criarem, editarem e exibirem quaisquer modelos de dados em seu site</li>
+ <li><strong>Serializando dados</strong>: O Django facilita a serialização e a veiculação de dados como XML ou JSON. Isso pode ser útil ap criar um serviço Web (um site que serve apenas para que dados sejam consumidos por outros aplicativos ou sites e não exibe nada por si só), ou ao criar um site no qual o código do lado do cliente lida com todas as renderizações.</li>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Parabéns, você completou o primeiro passo em sua jornada no Django! Agora você deve entender os principais benefícios do Django, um pouco sobre sua história e aproximadamente como podem ser as partes principais de um aplicativo Django. Você também deve ter aprendido algumas coisas sobre a linguagem de programação Python, incluindo a sintaxe para listas, funções e classes.</p>
+
+<p>Você já viu algum código real do Django acima, mas, diferentemente do código do lado do cliente, você precisa configurar um ambiente de desenvolvimento para executá-lo. Esse é o nosso próximo passo.</p>
+
+<div>{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}</div>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Introdução">Introdução ao Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website"> Parte 2: Criando um esqueleto de site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Models"> Parte 3: Usando moldes</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Admin_site"> Parte 4: Site administrador do Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Home_page"> Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Generic_views"> Parte 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Sessions"> Parte 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Authentication"> Parte 8: Autenticação de usuário e permissões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Forms"> Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Testing"> Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a><a href="/en-US/docs/Learn/Server-side/Django/Deployment"> Parte 11: Implantando o Django na produção</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Segurança da aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">Criando um mini blog Django</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/models/index.html b/files/pt-br/learn/server-side/django/models/index.html
new file mode 100644
index 0000000000..f0a5a3ca28
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/models/index.html
@@ -0,0 +1,459 @@
+---
+title: 'Tutorial Django Parte 3: Usando models'
+slug: Learn/Server-side/Django/Models
+translation_of: Learn/Server-side/Django/Models
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Este artigo mostra como definir os modelos para o website <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>. Ele explica o que é um modelo, como ele é declarado e mostra algum dos principais tipos de campo. Ele também mostra brevemente algumas das principais formas pelas quais você pode acessar dados do modelo.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Criar um esqueleto de um site</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Ser capaz de projetar e criar seus próprios modelos, escolhendo os campos de forma apropriada.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Geral">Visão Geral</h2>
+
+<p>Aplicativos Django acessam e gerenciam dados através de objetos Python chamados de modelos (models). Modelos definem a <em>estrutura</em> dos dados armazenados, incluindo os tipos de campos e possivelmente também o seu tamanho máximo, valores default, opções de listas de seleção, texto de ajuda para documentação, texto de labels para formulários, etc. A definição do modelo é independente do banco de dados - você pode escolher um tipo de banco como parte das configurações do seu projeto. Uma vez que você tenha escolhido qual banco será utilizado você precisa conversar diretamente com ele - você somente escreve a estrutura do seu modelo e outros códigos, e o Django faz todo o trabalho sujo de comunicação com o banco para você.</p>
+
+<p>Este tutorial mostra como definir e acessar os modelos para o website <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary website</a>.</p>
+
+<h2 id="Projetando_os_modelos_para_o_website_LocalLibrary">Projetando os modelos para o website <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a></h2>
+
+<p>Antes de começarmos a criar nossos modelos, vale a pena perder alguns minutos pensando sobre os dados que iremos guardar e as relações entre os diferentes modelos que serão criados.</p>
+
+<p>Sabemos que precisamos armazenar informação sobre os livros (título, resumo, autor, idioma, gênero, ISBN) e também que existem várias cópias do mesmo livro na biblioteca (com um id único, status de disponibilidade, etc.). Talvez queiramos armazenar mais informações sobre o autor além de somente seu nome, até porque existem vários autores com o mesmo nome, ou com nomes parecidos. Queremos ordernar a busca dos livros por título, autor, idioma e gênero.</p>
+
+<p>Quando estamos projetando nossos modelos, faz sentido criar modelos separados para cada "objeto". Em nosso caso de estudo, os "objetos" são os livros (a informação de cada livro, não a cópia em si), as cópias dos livros (um livro pode ter mais de uma cópia) e os autores.</p>
+
+<p>Você pode também utilizar modelos para representar opções em uma lista de seleção (por exemplo numa lista suspensa), o que é melhor do que trabalhar com opções predefinidas — isso é recomendado quando nem todas as opções são conhecidas ou podem mudar de acordo com um filtro. Obviamente, para nosso tutorial, modelos candidatos para esse caso são o gênero e o idioma.</p>
+
+<p>Após decidirmos nossos modelos e campos, precisamos pensar no relacionamento dessas informações. Django permite que você defina relações que são um pra um (<code>OneToOneField</code>), um pra muitos (<code>ForeignKey</code>) e muitos pra muitos (<code>ManyToManyField</code>).</p>
+
+<p>Com isso em mente, os diagramas UML de associação, mostram abaixo os modelos que definiremos nesse caso (como caixas).</p>
+
+<p><img alt="LocalLibrary Model UML" src="https://mdn.mozillademos.org/files/15646/local_library_model_uml.png" style="height: 660px; width: 977px;"></p>
+
+<p><span lang="pt">Como acima, criamos modelos para <code>Book </code>(que contém os detalhes genéricos do livro),<br>
+ <code>BookInstance</code> (contém os status das cópias físicas e específicas dos livros disponíveis no sistema) e <code>Author.</code> Também decidimos ter um modelo para o gênero (<code>Genre</code>), para que os valores possam ser criados/selecionados através da interface administrativa. Decidimos não ter um modelo para o <code>BookInstance: status</code> - pois, codificamos os valores em (<code>LOAN_STATUS</code>) porque não esperamos que isso mude. Dentro de cada uma das caixas você pode ver o nome do modelo, os campos nomes e tipos e também os métodos e seus tipos de retorno.</span></p>
+
+<p><span lang="pt">O diagrama também mostra as relações entre os modelos, incluindo suas multiplicidades. As multiplicidades são os números no diagrama que mostram as quantidades (máxima e mínima) que cada modelo pode estar presente nos relacionamentos. Por exemplo, a linha que conecta as caixas mostra que <code>Book</code> e um <code>Genre</code> estão relacionados. Os números próximos ao modelo <code>Genre</code> mostram que um livro deve ter um ou mais gêneros (ou quantos você quiser), enquanto os números do outro lado da linha, ao lado do modelo <code>Book</code> mostram que um gênero pode ter zero ou muitos livros associados.</span></p>
+
+<div class="note">
+<p><strong>Nota</strong>: A próxima seção fornece uma explicação básica sobre como os modelos são definidos e usados. Ao ler sobre isso, considere como vamos construir cada um dos modelos conforme o diagrama acima.</p>
+</div>
+
+<h2 id="Model_primer">Model primer</h2>
+
+<p>Esta seção fornece uma breve visão sobre como um modelo é definido e alguns dos mais importantes campos e argumentos dos campos.</p>
+
+<h3 id="Definição_do_Modelo">Definição do Modelo</h3>
+
+<p>Modelos são geralmente definidos no arquivo <strong>models.py</strong> em uma aplicação. Eles são implementados como subclasse de <code>django.db.models.Model</code>, e podem incluir campos, métodos e metadados. O fragmento de código abaixo, mostra um modelo "típico", chamado <code>MyModelName</code>:</p>
+
+<pre class="notranslate">from django.db import models
+
+class MyModelName(models.Model):
+    """Uma típica classe definindo um modelo, derivada da classe Model."""
+
+  # Campos
+    my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')
+  ...
+
+  # Metadados
+ class Meta:
+  ordering = ['-my_field_name']
+
+  # Métodos
+    def get_absolute_url(self):
+        """Retorna a url para acessar uma instancia específica de MyModelName."""
+        return reverse('model-detail-view', args=[str(self.id)])
+
+    def __str__(self):
+ """ String para representar o objeto MyModelName (no site Admin)."""
+        return self.my_field_name</pre>
+
+<p>Nas seções abaixa, exploraremos detalhadamente cada um dos recursos dentro do modelo:</p>
+
+<h4 id="Campos_Fields">Campos (Fields)</h4>
+
+<p>Um modelo pode ter um número árbitrário de campos, de qualquer tipo -- cada um representa uma coluna de dados que queremos armazenar em uma de nossas tabelas de banco de dados. Cada registro do banco de dados (row - linha) consitirá em um valor de cada campo. Vamos ver o exemplo visto acima:</p>
+
+<pre class="brush: js notranslate">my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')</pre>
+
+<div class="tw-swapa">
+<div class="DHcWmd"><span lang="pt">Nosso exemplo acima tem um único campo chamado <code>my_field_name</code>, do tipo <code>models.CharField</code> - o que significa que este campo conterá strings de caracteres alfanuméricos. Os tipos de cada campo são atribuídos usando classes específicas, que determinam o tipo de registro usado para armazenar os dados no banco de dados, juntamente com os critérios de validação a serem usados ​​quando os valores são recebidos de um formulário HTML (ou seja, o que constitui um valor válido). Os tipos de cada campo também podem receber argumentos que especifiquem como o campo é armazenado ou pode ser usado. Neste caso, estamos dando ao nosso campo dois argumentos:</span></div>
+
+<div class="DHcWmd"></div>
+</div>
+
+<ul>
+ <li><code>max_length=20</code> — Afima que o valor máximo do comprimento desse campo é de 20 caracteres.</li>
+ <li><code>help_text='Enter field documentation'</code> — <span class="tlid-translation translation" lang="pt"><span title="">fornece um rótulo de texto para exibir uma ajuda para os usuários saberem qual valor fornecer, quando esse valor é inserido por um usuário por meio de um formulário HTML.</span></span></li>
+</ul>
+
+<p><span class="tlid-translation translation" lang="pt"><span title="">O nome do campo é usado para se referir a ele em consultas e modelos.</span> <span title="">Os campos também têm um rótulo, que é especificado como um argumento <code>(verbose_name)</code> ou inferido ao capitalizar a primeira letra do nome da variável do campo e substituindo quaisquer sublinhados por um espaço (por exemplo,<code> my_field_name</code> teria um rótulo padrão de <code>My field name</code>).</span></span></p>
+
+<p><span class="tlid-translation translation" lang="pt"><span title="">A ordem em que os campos são declarados afetará sua ordem padrão, se um modelo for representado em um formulário (por exemplo, no site Admin), embora isso possa ser substituído.</span></span></p>
+
+<h5 id="Argumentos_comuns_de_um_campo">Argumentos comuns de um campo</h5>
+
+<p>Os seguintes argumentos são comuns e podem ser usados quando declaramos muitos ou a maioria dos diferentes tipos de campos:</p>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#help-text">help_text</a>: <span class="tlid-translation translation" lang="pt"><span title="">Fornece um rótulo de texto para formulários HTML (por exemplo, no site admin), conforme descrito acima.</span></span></li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#verbose-name">verbose_name</a>: <span class="tlid-translation translation" lang="pt"><span title="">Um nome legível para o campo usado nos rótulos de campo.</span> <span title="">Se não for especificado, o Django irá inferir o nome detalhado do campo <code>name</code>.</span></span></li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#default">default</a>: <span class="tlid-translation translation" lang="pt"><span title="">O valor padrão para o campo.</span> <span title="">Isso pode ser um valor ou um objeto que pode ser chamado. Cada vez que o objeto for chamado será criado um novo registro.</span></span></li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#null">null</a>: <span class="tlid-translation translation" lang="pt"><span title="">Se for <code>True</code>, o Django armazenará valores em branco como <code>NULL</code> no banco de dados, para campos onde isso é apropriado (um <code>CharField </code>irá armazenar uma string vazia).</span> <span title="">O padrão é <code>False</code></span></span>.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#blank">blank</a>:<span class="tlid-translation translation" lang="pt"><span title="">Se for <code>True</code>, o campo poderá ficar em branco nos seus formulários.</span> <span title="">O padrão é <code>False</code>, o que significa que a validação de formulário do Django forçará você a inserir um valor.</span> <span title="">Isso é frequentemente usado com <code>null = True</code>, porque se você permitir valores em branco, também desejará que o banco de dados possa representá-los adequadamente.</span></span></li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#choices">choices</a>: <span class="tlid-translation translation" lang="pt"><span title="">Um grupo de escolhas para este campo.</span> <span title="">Se isso for fornecido, o padrão widget de formulário correspondente será uma caixa de seleção com essas opções, em vez do campo de texto padrão.</span></span></li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#primary-key">primary_key</a>:<span class="tlid-translation translation" lang="pt"><span title="">Se <code>True,</code> define o campo atual como a chave primária do modelo (uma chave primária é uma coluna especial do banco de dados, designada para identificar exclusivamente as diferentes tabelas) .</span> <span title="">Se nenhum campo for especificado como a chave primária, o Django adicionará automaticamente um campo para essa finalidade.</span></span></li>
+</ul>
+
+<p><span class="tlid-translation translation" lang="pt"><span title="">Existem muitas outras opções - você pode ver</span></span> <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-options">a lista completa de opções aqui</a>.</p>
+
+<h5 id="Tipos_comuns_de_um_campo">Tipos comuns de um campo</h5>
+
+<p>A lista a seguir descreve alguns dos tipos de campos mais usados.</p>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.CharField">CharField</a> é usado para definir um tamanho fixo (médio a curto) para a string. Você deve especificar o <code>max_length (tamanho máximo) para o dado que será armazenado.</code></li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.TextField">TextField</a> é usado para grandes strings de comprimento variado. Você pode especificar um <code>max_length</code> (tamanho máximo) para o campo, mas isso é usado somente quando o campo é exibido em formulários (forms) (ele não é imposto no nível do banco de dados).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.IntegerField" title="django.db.models.IntegerField">IntegerField</a> é um campo para armazenar números inteiros e para validar valores inseridos como números inteiros em formulários.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#datefield">DateField</a> e <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#datetimefield">DateTimeField</a> são usados para armazenar / representar datas e informações de data / hora (como os objetos Python <code>datetime.date</code> in e <code>datetime.datetime</code>, respectivamente). Esses campos também podem declarar os parâmetros (mutuamente exclusivos) <code>auto_now = True</code> (para definir o campo para a data atual toda vez que o modelo é salvo), <code>auto_now_add</code> (para definir a data em que o primeiro modelo foi criado) e <code>default</code> (para definir uma data padrão que pode ser substituída pelo usuário).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#emailfield">EmailField</a> é usada para armazenara e validar em endereço de email.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#filefield">FileField</a> e <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#imagefield">ImageField</a> são usados para carregar arquivos e imagens respectivamente, (o <code>ImageField</code> simplesmente valida de forma adicional que o arquivo enviado é uma imagem). Eles têm parâmetros para definir como e onde os arquivos enviados são armazenados.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#autofield">AutoField</a> é um tipo especial de <code>IntegerField</code> que é incrementada automaticamente. Uma chave primária desse tipo é adicionada de forma automatica ao seu modelo, se você não especificar explicitamente um.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#foreignkey">ForeignKey</a> é usado para especificar um relacionamento um-para-muitos com outro modelo do banco de dados (por exemplo, um carro tem um fabricante, mas um fabricante pode fazer muitos carros). O lado "um" do relacionamento é o modelo que contém a "chave" (os modelos que contêm uma "chave estrangeira" referem-se a essa "chave" e estão no lado "muitos" de tal relacionamento).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#manytomanyfield">ManyToManyField</a> é usado para especificar um relacionamento muitos-para-muitos (por exemplo, um livro pode ter vários gêneros e cada gênero pode conter vários livros). Em nosso aplicativo de biblioteca, usaremos isso de maneira muito semelhante às <code>ForeignKeys</code>, mas elas podem ser usadas de maneiras mais complicadas para descrever as relações entre os grupos. Eles têm o parâmetro <code>on_delete</code> para definir o que acontece quando o registro associado é excluído (por exemplo, um valor de <code>models.SET_NULL</code> simplesmente definiria o valor como <code>NULL</code>).</li>
+</ul>
+
+<p>Existem muitos outros tipos de campos, incluindo campos para diferentes tipos de números (big integers, small integers, floats), booleanos, URLs, slugs, unique ids e outras informações "relacionadas ao tempo" (duração, tempo, etc.) . Você pode ver a <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types">lista completa AQUI</a>.</p>
+
+<h4 id="Metadados_metadada">Metadados (metadada)</h4>
+
+<p>Você pode declarar o nível de modelo para os metadados declarando <code>class Meta</code>, como mostrado.</p>
+
+<pre class="brush: python notranslate">class Meta:
+ ordering = ['-my_field_name']
+</pre>
+
+<p>Um dos recursos mais úteis desses metadados é controlar a ordem padrão dos registros retornados, quando você consulta o tipo de modelo. Você faz isso especificando a ordem de correspondência em uma lista de nomes para ordenar (<code>ordering</code>) o atributo , conforme mostrado acima. A ordem dependerá do tipo de campo (os campos de caractere são classificados em ordem alfabética, enquanto os campos de data são classificados em ordem cronológica). Como mostrado acima, você pode prefixar o nome do campo com um símbolo de menos (-) para inverter a ordem de classificação.</p>
+
+<p>Então, como exemplo, se optássemos por ordenar livros como este por padrão:</p>
+
+<pre class="brush: python notranslate">ordering = ['title', '-pubdate']</pre>
+
+<p>Os livros seriam classificados em ordem alfabética por título, de A-Z e depois por data de publicação dentro de cada título, do mais recente ao mais antigo.</p>
+
+<p>Outro atributo comum é <code>verbose_name</code>, um nome detalhado para a classe no singular e plural:</p>
+
+<pre class="brush: python notranslate">verbose_name = 'BetterName'</pre>
+
+<p>Outros atributos úteis permitem que você crie e aplique novas "permissões de acesso" para o modelo (as permissões padrão são aplicadas automaticamente), permitem a ordenação com base em outro campo ou declarar que a classe é "abstrata" (uma classe base que você não pode criar registros, e em vez disso, serão derivadas para criar outros modelos).</p>
+
+<p>Muitas das outras opções de metadados controlam qual banco de dados deve ser usado para o modelo e como os dados são armazenados (eles são realmente úteis somente se você precisar mapear um modelo para um banco de dados existente).</p>
+
+<p>A lista completa de opções de metadados pode ser encontrada aqui: <a href="https://docs.djangoproject.com/en/2.1/ref/models/options/">Opções de modelos de metadados</a> (Django docs).</p>
+
+<h4 id="Métodos">Métodos</h4>
+
+<p>Um modelo também pode ter métodos.</p>
+
+<p><strong>Minimamente, em cada modelo você deve definir o método de classe padrão do Python <code>__str__()</code> para retornar uma string legível para cada objeto.</strong> Essa sequência é usada para representar registros individuais no site de administração (e em qualquer outro lugar que você precise se referir a uma instância de modelo). Muitas vezes isso retornará um campo de título ou nome do modelo.</p>
+
+<pre class="brush: python notranslate">def __str__(self):
+  return self.field_name</pre>
+
+<p>Outro método comum a incluir nos modelos do Django é o <code>get_absolute_url()</code>, que retorna uma URL para exibir registros de modelos individuais no site (se você definir esse método, o Django adicionará automaticamente um botão "View on Site" às ​​telas de edição de registros do modelo o site Admin). Um padrão típico para <code>get_absolute_url ()</code> é mostrado abaixo.</p>
+
+<pre class="brush: python notranslate">def get_absolute_url(self):
+ """Retorna o URL para acessar uma instância específica do modelo."""
+ return reverse('model-detail-view', args=[str(self.id)])
+</pre>
+
+<div class="note">
+<p><strong>Nota: </strong>Supondo que você usará URLs como <code>/ myapplication / mymodelname / 2</code> para exibir registros individuais para seu modelo (onde "2" é o <code>id</code> para um registro específico), você precisará criar um mapeador de URL para passar a resposta e id para uma "vista detalhada do modelo" (que fará o trabalho necessário para exibir o registro). A função <code>reverse ()</code> acima é capaz de "inverter" seu mapeador de url (no caso acima chamado 'model-detail-view') para criar uma URL do formato correto.</p>
+
+<p>Claro que para fazer este trabalho você ainda tem que escrever o mapeamento de URL, visão e modelo!</p>
+</div>
+
+<p>Você também pode definir outros métodos que desejar e chamá-los de seu código ou modelos (desde que eles não utilizem nenhum parâmetro).</p>
+
+<h3 id="Gestão_de_modelos">Gestão de modelos</h3>
+
+<p>Depois de definir suas classes de modelo, você pode usá-las para criar, atualizar ou excluir registros e executar consultas para obter todos os registros ou subconjuntos específicos de registros. Mostraremos como fazer isso no tutorial quando definirmos nossas visualizações, mas aqui está um breve resumo.</p>
+
+<h4 id="Criando_e_modificando_registros">Criando e modificando registros</h4>
+
+<p>Para criar um registro, você pode definir uma instância do modelo e, em seguida, chamar <code>save ()</code>.</p>
+
+<pre class="brush: python notranslate"># Crie um novo registro usando o construtor do modelo.
+record = MyModelName(my_field_name="Instance #1")
+
+# Salve o objeto no banco de dados.
+record.save()
+</pre>
+
+<div class="note">
+<p><strong>Nota:</strong> Se você não tiver declarado qualquer campo como primary_key, o novo registro receberá um automaticamente, com o ID do nome do campo. Você poderia consultar este campo depois de salvar o registro acima e ele teria um valor de 1.</p>
+</div>
+
+<p>Você pode acessar os campos nesse novo registro usando a sintaxe de ponto e alterar os valores. Você precisa chamar <code>save ()</code> para armazenar valores modificados no banco de dados.</p>
+
+<pre class="brush: python notranslate"># Acessar valores de campo de modelo usando atributos do Python.
+print(record.id) # should return 1 for the first record.
+print(record.my_field_name) # should print 'Instance #1'
+
+# Altere o registro modificando os campos e, em seguida, chamando save ().
+record.my_field_name = "New Instance Name"
+record.save()</pre>
+
+<h4 id="Procurando_por_registros">Procurando por registros</h4>
+
+<p>Você pode procurar registros que correspondam a um determinado critério usando o atributo de objetos do modelo (fornecido pela classe base).</p>
+
+<div class="note">
+<p><strong>Nota: </strong>Explicar como procurar registros usando nomes de campos e modelos "abstratos" pode ser um pouco confuso. Na discussão abaixo, vamos nos referir a um modelo de livro com campos de título e gênero, onde o gênero também é um modelo com um único <code>nome</code> de campo.</p>
+</div>
+
+<p>Podemos obter todos os registros para um modelo como um <code>QuerySet</code>, usando<code> objects.all ()</code>. O <code>QuerySet</code> é um objeto iterável, o que significa que ele contém um número de objetos que podemos iterar / percorrer.</p>
+
+<pre class="brush: python notranslate">all_books = Book.objects.all()
+</pre>
+
+<p>O método <code>filter ()</code> do Django nos permite filtrar o <code>QuerySet</code> retornado para corresponder a um campo especificado de <strong>texto</strong> ou <strong>numérico</strong> em relação a um critério específico. Por exemplo, para filtrar por livros que contenham "wild" no título e, em seguida, contá-los, poderíamos fazer o seguinte.</p>
+
+<pre class="brush: python notranslate">wild_books = Book.objects.filter(title__contains='wild')
+number_wild_books = Book.objects.filter(title__contains='wild').count()
+</pre>
+
+<p>Os campos a serem correspondidos e o tipo de correspondência são definidos no nome do parâmetro de filtro, usando o formato: field_name__match_type (observe o sublinhado duplo entre título e contém acima). Acima, estamos filtrando o título com uma correspondência de maiúsculas e minúsculas. Existem muitos outros tipos de correspondência que você pode fazer: icontains (insensitivo a maiúsculas e minúsculas), iexact (correspondência exata que não diferencia maiúsculas e minúsculas), exata (correspondência exata diferencia maiúsculas de minúsculas), gt (maior que), startswith, etc. é <a href="https://docs.djangoproject.com/en/2.1/ref/models/querysets/#field-lookups">aqui</a>.</p>
+
+<p>Em alguns casos, você precisará filtrar um campo que defina um relacionamento um-para-muitos com outro modelo (por exemplo, uma <code>ForeignKey</code>). Nesse caso, você pode "indexar" campos no modelo relacionado com sublinhados duplos adicionais. Por exemplo, para filtrar livros com um padrão de gênero específico, você terá que indexar o <code>nome</code> por meio do campo de <code>gênero</code>, conforme mostrado abaixo:</p>
+
+<pre class="brush: python notranslate"># Combinará em: ficção, ficção científica, não-ficção etc.
+books_containing_genre = Book.objects.filter(genre<strong>__</strong>name<strong>__</strong>icontains='fiction')
+</pre>
+
+<div class="note">
+<p><strong>Nota:</strong> Você pode usar sublinhados (__) para navegar quantos níveis de relacionamentos (<code>ForeignKey / ManyToManyField</code>) desejar. Por exemplo, um <code>Livro</code> que tinha tipos diferentes, definidos usando um relacionamento "cover" adicional, pode ter um nome de parâmetro: <code>type__cover__name__exact = 'hard'</code>.</p>
+</div>
+
+<p>Há muito mais que você pode fazer com as consultas, incluindo pesquisas para trás de modelos relacionados, encadeando filtros, retornando um conjunto menor de valores, etc. Para obter mais informações, consulte <a href="https://docs.djangoproject.com/en/2.1/topics/db/queries/">Fazendo consultas</a> (Django Docs).</p>
+
+<h2 id="Definindo_os_modelos_LocalLibrary">Definindo os modelos LocalLibrary</h2>
+
+<p>Nesta seção, começaremos a definir os modelos para a biblioteca. Abra models.py (em / locallibrary / catalog /). O código na parte superior da página importa o módulo de models, que contém os modelos da classe base do models. Modelo do qual nossos models herdarão.</p>
+
+<pre class="brush: python notranslate">from django.db import models
+
+# Create your models here.</pre>
+
+<h3 id="Genre_model">Genre model</h3>
+
+<p>Copie o código do model <code>Genre</code> , que aparece a baixo, e cole no seu arquivo <code>models.py</code> , abaixo do código de importação.  Esse model  guarda informaçoes sobre a categoria do livro — por exemplo se é ficção ou não ficção, romance ou história, etc. Como mencionado acima, criamos o genero como um model em vez de um campo de texto ou um lista de seleção para que os possíveis generos criados possam ser gerenciados pelo banco de dados, em vez de serem codificados.</p>
+
+<pre class="syntaxbox notranslate">class Genre(models.Model):
+ """Model representing a book genre."""
+ name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
+
+ def __str__(self):
+ """String for representing the Model object."""
+ return self.name</pre>
+
+<p class="syntaxbox">O model tem apenas um campo do tipo <code>CharField</code> (<code>name</code>), que é usado para descrever o genero (esse campo é limitado a 200 caracteres e tem um <code>help_text</code>). No final da classe Genre declaramos o metodo  <code>__str__()</code> que retorna o nome do genero definido por um registro especifico. Não foi definido um argumento <code>verbose_name</code> , assim o campo será referenciado como  <code>Name</code> nos forms.</p>
+
+<h3 id="Book_model">Book model</h3>
+
+<p>Copie o model Book abaixo e cole novamente ao final do seu arquivo. O model Book representa todas as informações disponíveis sobre um livro de maneira geral, mas não incluí detalhes sobre o formato do encadernamento ou disponibilidade para empréstimo. O model usa um <code>CharField</code> para representar o  <code>title</code> (tílutlo) do livro e o <code>isbn</code> (veja que o <code>isbn</code> recebe um rótulo como "ISBN", usando o primeiro parâmetro não nomeado, porque, de outra forma, o rótulo ficaria "Isbn"). O model usa <code>TextField</code> para o campo <code>summary</code> porque ele precisa ser um tanto longo.</p>
+
+<pre class="notranslate">from django.urls import reverse # Used to generate URLs by reversing the URL patterns
+
+class Book(models.Model):
+    """Model representing a book (but not a specific copy of a book)."""
+    title = models.CharField(max_length=200)
+
+ # Foreign Key used because book can only have one author, but authors can have multiple books
+ # Author as a string rather than object because it hasn't been declared yet in the file
+    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
+
+    summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book')
+    isbn = models.CharField('ISBN', max_length=13, help_text='13 Character &lt;a href="https://www.isbn-international.org/content/what-isbn"&gt;ISBN number&lt;/a&gt;')
+
+    # ManyToManyField used because genre can contain many books. Books can cover many genres.
+    # Genre class has already been defined so we can specify the object above.
+ genre = models.ManyToManyField(Genre, help_text='Select a genre for this book')
+
+    def __str__(self):
+        """String for representing the Model object."""
+        return self.title
+
+    def get_absolute_url(self):
+        """Returns the url to access a detail record for this book."""
+        return reverse('book-detail', args=[str(self.id)])</pre>
+
+<p>Genre é um campo <code>ManyToManyField</code>, de forma que um livro pode ter múltiplos gêneros e um gênero pode ter muitos livros. O campor Author é declarado como um <code>ForeignKey</code>, logo, cada livro terá somente um autor, mas um autor por der muitos livros (na prática, um livro pode ter múltiplos autores, mas não nesta implementação!)</p>
+
+<p>Em ambos tipos de campo, a classe model relacionada é declarada como primeiro campo não nomeado usando a classe model ou contendo o nome do modelo relacionado. Você deve usar o nome do model como uma string se a classe associada ainda não tiver sido definida no arquivo, antes de referenciá-la. Outro parâmetro de interesse no campo <code>author</code> é <code>null=True</code>, o qual permite ao banco de dados armazer um valor <code>Null</code> se nenhum autor for selecionado, e, <code>on_delete=models.SET_NULL</code>, o qual definirá o valor <code>author</code> como <code>Null</code> se o registro do autor associado for excluído.</p>
+
+<p>O mode também defini <code>__str__()</code>, usando o <code>title</code> do livro para representar o registro do <code>Book</code>. O método final, <code>get_absolute_url()</code>, retorna a URL que pode ser usada para acessar o registro detalhado deste modelo (para que isto funcione, teremos que definir um mapa de URL com o nome <code>book-detail</code> e associá-la a uma view e a um template.).</p>
+
+<h3 id="BookInstance_model">BookInstance model</h3>
+
+<p>Em seguida, copie o modelo <code>BookInstance</code> (exibido a abaixo) depois dos outros modelos. O <code>BookInstance</code> representa um exemplar específico do livro que pode ser emprestado, indica se ela está disponível ou a data programada de restituição, "imprint" ou detalhes da versão, e, um id único do livro na biblioteca.</p>
+
+<p>Alguns dos campos e métodos serão familiares agora. O model usa</p>
+
+<ul>
+ <li><code>ForeignKey</code> para identificar o <code>Book</code> associado (cada livro pode ter muitos exemplares, porém uma cópia pode ter sometne um <code>Book</code>).</li>
+ <li><code>CharField</code> para representar o imprint (edição específica) do livro.</li>
+</ul>
+
+<pre class="brush: python notranslate">import uuid # Required for unique book instances
+
+class BookInstance(models.Model):
+ """Model representing a specific copy of a book (i.e. that can be borrowed from the library)."""
+ id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular book across whole library')
+ book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
+ imprint = models.CharField(max_length=200)
+ due_back = models.DateField(null=True, blank=True)
+
+ LOAN_STATUS = (
+ ('m', 'Maintenance'),
+ ('o', 'On loan'),
+ ('a', 'Available'),
+ ('r', 'Reserved'),
+ )
+
+ status = models.CharField(
+ max_length=1,
+ choices=LOAN_STATUS,
+ blank=True,
+ default='m',
+ help_text='Book availability',
+ )
+
+ class Meta:
+ ordering = ['due_back']
+
+ def __str__(self):
+ """String for representing the Model object."""
+ return f'{self.id} ({self.book.title})'</pre>
+
+<p>Nós declaramos adicionalmente alguns tipos novos de campos:</p>
+
+<ul>
+ <li><code>UUIDField</code> é usado no campo <code>id</code> para definí-lo como <code>primary_key</code> deste model. Este tipo de campo aloca um valor único global para cada instância (um para cada livro encontrado na biblioteca).</li>
+ <li><code>DateField</code> é usado para a data <code>due_back</code> (na qual o livro deve retonar e ficar disponível após um empréstimo ou uma manutenção). O valor pode ser <code>blank</code> ou <code>null</code> (para quando o livro estiver disponível). O model metadata (<code>Class Meta</code>) usa este campo para ordenar os registros quando eles são retornados em uma query.</li>
+ <li><code>status</code> é um <code>CharField</code> que define uma lista de opção/seleção. Como pode ser visto, nós definimos uma dupla contendo pares de valores-chave e a passamos no argumento da opção. O valor do par valor-chave é um valor que o usuário pode selecionar, enquanto que a chave é o valor que  realmetne será salvo se a opção for selecionada. Nós também definimos um valor default como "m" (maintenance), uma vez que os livros serão inicialmente criados como indisponíveis até que eles sejam disponibilizados nas prateleiras.</li>
+</ul>
+
+<p>O model <code>__str__()</code> representa o objeto <code>BookInstance</code> usando a combinação do seu id único e o título do <code>Book</code> associado.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Um pouco sobre Python:</p>
+
+<ul>
+ <li>Começando com Python 3.6, pode ser usada a sintaxe de interpolação  (também conhecida como f-strings): <code>f'{self.id} ({self.book.title})'</code>.</li>
+ <li>Em versões anteriores deste tutorial, nós estávamos usando a sintaxe de  <a href="https://www.python.org/dev/peps/pep-3101/">formatted string</a>, a qual também é uma maneira válida de formatar  strings em Python (e.g. <code>'{0} ({1})'.format(self.id,self.book.title)</code>).</li>
+</ul>
+</div>
+
+<h3 id="Author_model">Author model</h3>
+
+<p>Copie o model <code>Author</code> (exibido abaixo) na sequência do código existente em  <strong>models.py</strong>.</p>
+
+<p>Todos os campos/métodos já devem ser familiares agora. O model define um autor como tendo um nome, sobrenome, data de nascimento e data de morte (opcionalmente). Ele especifica que <code>__str__()</code> retorna por default sobrenome e nome, nesta ordem. O método <code>get_absolute_url()</code> reverte o mapaeamento da URL <code>author-detail</code> para obter a URL de display individual author.</p>
+
+<pre class="brush: python notranslate">class Author(models.Model):
+    """Model representing an author."""
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    class Meta:
+        ordering = ['last_name', 'first_name']
+
+    def get_absolute_url(self):
+        """Returns the url to access a particular author instance."""
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        """String for representing the Model object."""
+        return f'{self.last_name}, {self.first_name}'
+
+</pre>
+
+<h2 id="Rode_novamente_a_migração_do_banco_de_dados">Rode novamente a migração do banco de dados</h2>
+
+<p>Todos os modelos foram criados. Agora rode a migração do banco de dados para adicioná-los ao seu banco de dados.</p>
+
+<pre class="notranslate"><code>python3 manage.py makemigrations
+python3 manage.py migrate</code></pre>
+
+<h2 id="Language_model_—_desafio">Language model — desafio</h2>
+
+<p>Considere que um benfeitor local doe uma quantidade de livros escritos em outro idioma (digamos, Farsi). O desafio é desenvolver como eles seriam melhor representados no website da nossa biblioteca, e, então, adicioná-lo no models.</p>
+
+<p>Algumas coisas a considerar:</p>
+
+<ul>
+ <li>O idioma seria associado ao  <code>Book</code>, <code>BookInstance</code>, ou algum outro objeto?</li>
+ <li>Os diferentes idiomas seriam representados usando model, como campo de texto livre ou codificado como uma lista de seleção?</li>
+</ul>
+
+<p>Depois de decidido, adicione o campo. Pode ser visto o que decidimos no Github <a href="https://github.com/mdn/django-locallibrary-tutorial/blob/master/catalog/models.py">aqui</a>.</p>
+
+<ul>
+</ul>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Neste artículo vimos como os  models são definidos, e, então, usamos esta informação para desenhar e implementar modelos apropriados para o website  <em>LocalLibrary</em>.</p>
+
+<p>Neste ponto faremos um rápido desvio da criação do site para ver o <em>Django Administration site</em>. Este site nos permitirá adicionar alguns dados à biblioteca, os quais podemos então exibir usando nossos próprios views e templates (ainda não criados).</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial02/">Escrevendo nossa primeira app Django, parte 2</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/db/queries/">Fazendo queries</a> (Django Docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/querysets/">Referência a QuerySet API</a> (Django Docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma biblioteca local</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando o escopo do website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Parte 3: Utilizando models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Parte 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Segurança de aplicações Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/sessões/index.html b/files/pt-br/learn/server-side/django/sessões/index.html
new file mode 100644
index 0000000000..f2f16b521f
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/sessões/index.html
@@ -0,0 +1,205 @@
+---
+title: 'Tutorial Django Parte 7: Sessões'
+slug: Learn/Server-side/Django/Sessões
+tags:
+ - Artigo
+ - Iniciante
+ - Programação
+ - Python
+ - Script
+ - Servidor
+ - Tutorial
+ - aprenda
+ - django
+ - django português
+ - server-side
+ - sessões django
+translation_of: Learn/Server-side/Django/Sessions
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django")}}</div>
+
+<div>Esse tutorial estende nosso site <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, adicionando um contador de visitas baseado em sessões à página inicial. Esse é um exemplo relativamente simples, mas, capaz de mostrar como você pode usar a estrutura de sessão do framework para providenciar um comportamento persistente para usuários anônimos em seu próprio site.</div>
+
+<div></div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Completar todos os tópicos anteriores do tutorial, incluindo <a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Entender como as sessões são usadas.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Geral">Visão Geral</h2>
+
+<p>O site <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a> que criamos nos tutoriais anteriores permite que os usuarios busquem por livros e autores no catálogo. Enquanto o conteúdo é dinamicamente gerado a partir da base de dados, todos os usuários terão acessos às mesmas páginas e às mesmas informações quando acessarem o site.</p>
+
+<p><span class="tlid-translation translation"><span title="">Em uma biblioteca "real", você pode querer fornecer uma experiência personalizada para cada usuário, com base no uso anterior do site, nas preferências, etc. Por exemplo, você pode ocultar mensagens de aviso que o usuário reconheceu anteriormente na próxima visita deles ao</span> <span title="">site ou armazenar e respeitar suas preferências (por exemplo, o número de resultados de pesquisa que eles querem exibir em cada página).</span></span></p>
+
+<div class="text-wrap tlid-copy-target">
+<div class="result-shield-container tlid-copy-target"><span class="tlid-translation translation"><span title="">A estrutura da sessão permite implementar esse tipo de comportamento, permitindo que você armazene e recupere dados arbitrários baseados em cada visitante do site.</span></span></div>
+</div>
+
+<h2 id="O_que_são_sessões">O que são sessões?</h2>
+
+<p>Toda a comunicação entre os navegadores web e os servidores é feita via protocolo HTTP, qual é <em>stateless</em> (sem estados). O fato do protocolo ser stateless significa que as mensagenns entre o cliente e o servidor são completamente independentes uma da outra — não há uma noção de "sequência" ou comportamento diferente baseado nas mensagens anteriores. <span class="tlid-translation translation"><span title="">Como resultado, se você quiser ter um site que monitore os relacionamentos contínuos com um cliente, é necessário implementá-lo por conta própria.</span></span></p>
+
+<p>Sessões são o mecanismo usado pelo Django (e muitos outros na Internet) para monitorar o "estado" entre o site e um navegador web em particular. Sessões permitem que você armazene dados arbitrários por navegador web, e têm esse dado disponível no site sempre que o navegador conectar. Dados de itens individuais associados com a sessão são referenciados por uma "chave", que é usada para armazenar e recuperar os dados.</p>
+
+<p>O Django usa um cookie contendo um <em>identificador</em> especial de sessão para identificar cada navegador e associar com o site. Os dados da sessão atual são armazenados na base de dados do site por padrão (é mais seguro do que armazenar os dados em cookie, onde é mais vulnerável aos usuários perigisos). Você pode configurar o Django para armazenar os dados da sessão em outros lugares (cache, arquivos, cookies "seguros"), mas o local padrão é uma opção boa e relativamente "segura".</p>
+
+<h2 id="Habilitando_as_Sessões">Habilitando as Sessões</h2>
+
+<p>As sessões foram ativadas automaticamente quando <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">criamos o esqueleto do site</a> (no tutorial 2).</p>
+
+<p>A configuração e feita nas seções <code>INSTALLED_APPS</code> e <code>MIDDLEWARE</code> do arquivo (<strong>locallibrary/locallibrary/settings.py</strong>), exibidas a seguir:</p>
+
+<pre class="brush: python">INSTALLED_APPS = [
+ ...
+<strong> 'django.contrib.sessions',</strong>
+ ....
+
+MIDDLEWARE = [
+ ...
+<strong> 'django.contrib.sessions.middleware.SessionMiddleware',</strong>
+ ....</pre>
+
+<h2 id="Usando_Sessões">Usando Sessões</h2>
+
+<p>Você pode acessar o atributo <code>session</code> na view a partir do parâmetro <code>request</code> (um <code>HttpRequest</code> passado como primeiro argumento na view). Esse atributo de sessão representa a conexão atual específica com um usuário<span class="tlid-translation translation"><span title=""> (ou, para ser mais preciso, a conexão com o navegador atual, conforme identificado pelo id da sessão no cookie do navegador para este site)</span></span>.</p>
+
+<p>O atributo <code>session</code> é como um objeto dicionário que você pode ler e escrever quantas vezes você quiser na sua view, modificando-o como desejar. Você pode fazer todas as operações normais de um dicionário, incluindo limpar todos os dados, testar se uma chave está presente, loop em torno dos dados, etc. Na maior parte do tempo, você usará apenas a API padrão "dictionary" para obter e setar valores.</p>
+
+<p>O fragmento de código abaixo mostra como você pode obter, setar e deletar qualquer dado com com a chave "<code>my_car</code>", associada com a sessão atual (navegador).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Uma das coisas boas sobre o Django é que você não precisa pensar sobre os mecanismos que vinculam a sessão atual à requisição em sua view. Se nós usarmos os fragmentos abaixo em nossa view, saberemos que as informações sobre <code>my_car</code> estão associadas apenas com o navegador que enviou a requisição atual.</p>
+</div>
+
+<pre class="brush: python"># Pega um valor de sessão baseado na sua chave (ex.:'my_car'), disparando um KeyError se a chave não for encontrada.
+my_car = request.session['my_car']
+
+# Pega o valor da sessão, seta o valor padrão ('mini') se a chave não estiver presente.
+my_car = request.session.get('my_car', 'mini')
+
+# Seta o valor da sessão
+request.session['my_car'] = 'mini'
+
+# Deleta o valor da sessão
+del request.session['my_car']
+</pre>
+
+<p>A API também oferece um número de outros métodos que são muito usados para gerenciar a os cookies da sessão associada. Por exemplo, há metodos para testar se cookies são suportados no navegador do cliente, para setar e checar a data de validade do cookie, e para limpar sessões expiradas do armazenamento de dados. Você pode encontrar sobre a API completa em <a href="https://docs.djangoproject.com/en/2.1/topics/http/sessions/">How to use sessions</a> (documentação do Django).</p>
+
+<h2 id="Salvando_os_dados_da_sessão">Salvando os dados da sessão</h2>
+
+<p>Por padrão, o Django só salva na base de dados da sessão e envia o cookie da sessão para o cliente quando a sessão é <em>modificada </em>(atribuida) ou <em>deletada</em>. Se você está atualizando alguns dados utilizando sua chave de sessão, como mostrado na seção anterior, então você não precisa se preocupar com isso! Por exemplo:</p>
+
+<pre class="brush: python"># This is detected as an update to the session, so session data is saved.
+request.session['my_car'] = 'mini'</pre>
+
+<p>Se você está atualizando algumas informações <em>dentro </em>dos dados da sessão, então o Django não reconhecerá que você fez uma alteração nos dados da sessão e não salvará os dados (por exemplo, se você alterasse os dados de  "<code>wheels</code>"  dentro dos dados do seu "<code>my_car</code>", como mostrado abaixo). Nesse caso você precisará marcar explicitamente a sessão como tendo sido modificada.</p>
+
+<pre class="brush: python"># Session object not directly modified, only data within the session. Session changes not saved!
+request.session['my_car']['wheels'] = 'alloy'
+
+# Set session as modified to force data updates/cookie to be saved.
+<code>request.session.modified = True</code>
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Você pode mudar o comportamento do site para atualizar a base de dados/enviar cookie em qualquer requisição adicionando <code>SESSION_SAVE_EVERY_REQUEST = True</code> nas configurações (<strong>locallibrary/locallibrary/settings.py</strong>) do seu projeto.</p>
+</div>
+
+<h2 id="Exemplo_simples_-_obtendo_a_contagem_de_visitas">Exemplo simples - obtendo a contagem de visitas</h2>
+
+<p>Como um exemplo simples do mundo real, atualizaremos nossa biblioteca para informar ao usuário atual quantas vezes ele visitou o site <em>LocalLibrary</em>. </p>
+
+<p>Abra <strong>/locallibrary/catalog/views.py</strong>, e faça as alterações mostradas em negrito abaixo.</p>
+
+<pre class="brush: python">def index(request):
+ ...
+
+ num_authors = Author.objects.count() # The 'all()' is implied by default.
+
+<strong> # Number of visits to this view, as counted in the session variable.
+ num_visits = request.session.get('num_visits', 0)
+ request.session['num_visits'] = num_visits + 1</strong>
+
+<strong> context = {
+ 'num_books': num_books,
+ 'num_instances': num_instances,
+ 'num_instances_available': num_instances_available,
+ 'num_authors': num_authors,
+ 'num_visits': num_visits,
+ }</strong>
+
+ # Render the HTML template index.html with the data in the context variable.
+ return render(request, 'index.html', context=context)</pre>
+
+<p>Aqui primeiro obtemos o valor da  <em>session key</em> <code>'num_visits'</code>, setando o valor para 0 se não tiver sido definido anteiormente. Cada vez que uma requisição é recebida, nós então incrementamos o valor e armazenamos novamente na sessão (para a próxima vez que o usuário visitar a página). A variável <code>num_visits</code> é então passada para o <em>template</em> na nossa varável <em>context</em>.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Também podemos testar se os cookies são suportados no navegador (veja <a href="https://docs.djangoproject.com/en/2.1/topics/http/sessions/">Como usar sessões</a> para exemplos) ou projetar nossa UI (interface do usuário) para que não se importe se os <em>cookies</em> são ou não suportados.</p>
+</div>
+
+<p>Adicione a linha vista na parte inferior do bloco a seguir ao seu <em>template</em> HTML principal (<strong>/locallibrary/catalog/templates/index.html</strong>) na parte inferior da sessão <em>"Dynamic content"</em>, para exibir a variável <em>context</em>:</p>
+
+<pre class="brush: html">&lt;h2&gt;Dynamic content&lt;/h2&gt;
+
+&lt;p&gt;The library has the following record counts:&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;&lt;strong&gt;Books:&lt;/strong&gt; \{{ num_books }}&lt;/li&gt;
+ &lt;li&gt;&lt;strong&gt;Copies:&lt;/strong&gt; \{{ num_instances }}&lt;/li&gt;
+ &lt;li&gt;&lt;strong&gt;Copies available:&lt;/strong&gt; \{{ num_instances_available }}&lt;/li&gt;
+ &lt;li&gt;&lt;strong&gt;Authors:&lt;/strong&gt; \{{ num_authors }}&lt;/li&gt;
+&lt;/ul&gt;
+
+<strong>&lt;p&gt;You have visited this page \{{ num_visits }}{% if num_visits == 1 %} time{% else %} times{% endif %}.&lt;/p&gt;</strong>
+</pre>
+
+<p>Salve suas alterações e reinicie o servidor de teste. Sempre que você atualiza a página, o número deve ser atualizado.</p>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Agora você sabe como é fácil utilizar sessões para melhorar sua interação com usuários anônimos. </p>
+
+<p>Em nosso próximo artigo nós iremos explicar a estrutura de autenticação e autorização (permissão), e mostrar como oferecer suporte a contas de usuário.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/http/sessions/">Como usar sessões</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/Authentication", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: </a><a rel="nofollow" title="A página ainda não foi criada.">Website de uma Biblioteca Local</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Parte 2: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Criando a base do website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Models">Django Parte 3: Usando <em>models</em></a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Parte 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Parte 6: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Generic_views">Lista genérica e <em>detail views</em></a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Parte 7: </a><a rel="nofollow" title="A página ainda não foi criada.">Framework de Sessões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Parte 8: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Authentication">Autenticação de Usuário e permissões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Parte 9: </a><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Forms">Trabalhando com formulários</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Parte 10: </a><a rel="nofollow" title="A página ainda não foi criada.">Testando uma aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial</a> <a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Parte 11: </a><a rel="nofollow" title="A página ainda não foi criada.">Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/skeleton_website/index.html b/files/pt-br/learn/server-side/django/skeleton_website/index.html
new file mode 100644
index 0000000000..5a453131b2
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/skeleton_website/index.html
@@ -0,0 +1,393 @@
+---
+title: 'Django Tutorial Parte 2: Criando o "esqueleto" de um site'
+slug: Learn/Server-side/Django/skeleton_website
+tags:
+ - Artigo
+ - Guía
+ - Iniciante
+ - Python
+ - locallibrary
+translation_of: Learn/Server-side/Django/skeleton_website
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">O segundo artigo do tutorial de Django mostra uma forma de criar o "esqueleto" de um website, permitindo que você possa ampliá-lo com caracteristicas especificas do site, caminhos (patchs), modelos (models), visualizações (views) e templates. </p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurar um ambiente de desenvolvimento Django</a>. Ter lido <a href="https://developer.mozilla.org/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Ser capaz de usar as ferramentas do Django para começar seus próprios novos projetos de websites.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Geral">Visão Geral</h2>
+
+<p>Este artigo mostra como você pode criar o escopo de um website, permitindo popul-a-lo com características específicas do seu site, tais como configurações, paths, modelos, views e templates (nós os discutiremos em artigos que seguem à frente).</p>
+
+<p>O processo é direto:</p>
+
+<ol>
+ <li><span style="line-height: 1.5;">Use a ferramenta </span><code style="font-style: normal; font-weight: normal; line-height: 1.5;">django-admin</code><span style="line-height: 1.5;"> para criar a pasta do projeto, arquivos de template básicos, e o script de gestão do projeto (</span><strong style="line-height: 1.5;">manage.py</strong><span style="line-height: 1.5;">).</span></li>
+ <li><span style="line-height: 1.5;">Use o script </span><strong style="line-height: 1.5;">manage.py</strong><span style="line-height: 1.5;"> para criar um ou mais <em>aplicativos</em>.</span>
+ <div class="note">
+ <p><strong>Nota</strong>: Um website pode consistir de uma ou mais áreas,  como por exemplo, site, blog, wiki, área de download, etc. Django te encoraja a desenvolver esses componentes como aplicativos separados, que podem então ser reutilizados em diferentes projetos, caso seja necessário.</p>
+ </div>
+ </li>
+ <li><span style="line-height: 1.5;">Registre os novos aplicativos para inclui-los no projeto. </span></li>
+ <li><span style="line-height: 1.5;">Conecte o mapeador de url/path para cada aplicativo.</span></li>
+</ol>
+
+<p>Para o  <a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">website Biblioteca Local</a> a pasta do website e a pasta do projeto terão, ambas, o nome <em>locallibrary</em>, e nós teremos apenas um aplicativo chamado <em>catalog</em>. O nível hierárquico mais alto da estrutura de pastas ficará assim:</p>
+
+<pre class="brush: bash notranslate"><em>locallibrary/ # Pasta do website</em>
+  <strong>manage.py </strong> # Script para executara as ferramentas do Django para este projeto (criado utilizando o django-admin)
+  <em>locallibrary/ # Pasta do project folder </em>(criado utilizando o django-admin)
+ <em>catalog/ # Pasta do aplicativo </em>(criado utilizando o django-admin)
+</pre>
+
+<p><span style="line-height: 1.5;">As próximas seções discutem esse processo em detalhes e mostram como você pode testar as mudanças.  No final do artigo nós  discutiremos algumas das outras configurações do site como um todo, você também pode fazer isso.</span></p>
+
+<h2 id="Criando_o_projeto">Criando o projeto</h2>
+
+<p>Primeiro abra o prompt de comando/terminal t(enha certeza que está em seu <a href="/pt-BR/docs/Learn/Server-side/Django/ambiente_de_desenvolvimento">ambiente virtual)</a>, navegue até o diretório que deseja colocar seus aplicativos Django (coloque em um lugar fácil de achar, como dentro da pasta <em>documentos</em>), e crie uma pasta para seu novo website (nesse caso: <em>django_projects</em>). Acesse então a pasta usando o comando cd:</p>
+
+<pre class="brush: bash notranslate">mkdir locallibrary
+cd locallibrary</pre>
+
+<p>Crie um novo projeto usando o comando <code>django-admin startproject</code>, como mostrado abaixo, e entre nessa pasta.</p>
+
+<pre class="brush: bash notranslate">django-admin startproject locallibrary
+cd locallibrary</pre>
+
+<p>O comando <code>django-admin</code> cria uma estrutura com pastas e arquivos como a mostrada abaixo:</p>
+
+<pre class="brush: bash notranslate"><em>locallibrary/</em>
+  manage.py
+  <em>locallibrary/</em>
+ __init__.py
+    settings.py
+    urls.py
+    wsgi.py</pre>
+
+<p>Nosso diretório de trabalho atual deve parecer com isso:</p>
+
+<pre class="syntaxbox notranslate">../django_projects/locallibrary/</pre>
+
+<p>  A sub-pasta do projeto <em>locallibrary</em> será a raíz para nosso site:</p>
+
+<ul>
+ <li><strong>__init__.py </strong>é um arquivo em branco que instrui o Python a tratar esse diretório como um pacote Python.</li>
+ <li><strong>settings.py</strong> contém todas as definições do website. É onde nós registramos qualquer aplicação que criarmos, a localização de nossos arquivos estáticos, configurações de banco de dados etc. </li>
+ <li><strong>urls.py</strong> define os mapeamentos de URL para visualização do site<span style="line-height: 1.5;">. Mesmo que esse</span> arquivo possa conter <em>todo </em>o código para mapeamento de URL, é mais comum delegar apenas o mapeamento para aplicativos específicos, como será visto mais adiante.</li>
+ <li><strong style="line-height: 1.5;">wsgi.py</strong><span style="line-height: 1.5;"> é usado para ajudar na comunicação entre seu aplicativo Django e o web server. Você pode tratar isso como um boilerplate.</span></li>
+</ul>
+
+<p>O script <strong>manage.py</strong> é usado para criar aplicações, trabalhar com bancos de dados, e iniciar o webserver de desenvolvimento. </p>
+
+<h2 id="Criando_o_aplicativo_de_catálogo">Criando o aplicativo de catálogo</h2>
+
+<p>Agora execute o seguinte comando para criar o <em>catálogo</em> da aplicação que fará parte de nosso projeto localibrary (o comando deve ser executado na mesma pasta que está o <strong>manage.py</strong> do seu projeto):</p>
+
+<pre class="brush: bash notranslate">python3 manage.py startapp catalog</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: O comando acima é para Linux/macOS X. No windows o comando deve ser: <code>py -3 manage.py startapp catalog</code></p>
+
+<p>Se você  está trabalhando com o Windows, substitua <code>python3</code> por <code>py -3</code> ao longo deste módulo.</p>
+
+<p>Se você está usando Python 3.7.0, use <code>py manage.py startapp catalog</code></p>
+</div>
+
+<p>A ferramenta cria uma nova pasta e adiciona alguns arquivos para diferentes partes da aplicação (destacado em negrito abaixo). A maior parte dos arquivos é armazenada de acordo com seu propósito (e.g. views devem ser armazenadas em <strong>views.py</strong>, models em <strong>models.py</strong>, testes em <strong>tests.py</strong>, configurações de administração do site em <strong>admin.py</strong>, registro da aplicação em <strong>apps.py</strong>) e contém algum código mínimo para trabalhar com os objetos associados.</p>
+
+<p>O diretório do projeto atualizado deve parecer com esse:</p>
+
+<pre class="brush: bash notranslate"><em>locallibrary/</em>
+  manage.py
+  <em>locallibrary/
+</em><strong>  <em>catalog/</em>
+      admin.py
+      apps.py
+      models.py
+      tests.py
+      views.py
+      __init__.py
+  <em>migrations/</em></strong>
+</pre>
+
+<p>Além disso, nós temos:</p>
+
+<ul>
+ <li>Uma pasta <em>migrations</em>, usada para guardar "<em>migrações</em>" — arquivos que permitem atualizar automaticamente seu banco de dados à medida que você modifica seus models. </li>
+ <li><strong>__init__.py</strong> — Um arquivo em branco criado de modo que Django/Python reconheça a pasta como um <a href="https://docs.python.org/3/tutorial/modules.html#packages">Python Package</a> e permita que você use seus objetos dentro de outras partes do projeto.</li>
+</ul>
+
+<div class="note">
+<p><strong>Nota</strong>: Você notou o que falta na lista  de arquivos acima? Apesar de existir um lugar para suas views e seus models, não há nenhum lugar para colocar seus mapeamentos de URL, templates ou arquivos estáticos. Nós iremos te ensinar como criá-los mais adiante (isso não é necessário em todos websites, mas precisarem em nosso exemplo).</p>
+</div>
+
+<h2 id="Registrando_o_aplicativo_de_catálogo">Registrando o aplicativo de catálogo</h2>
+
+<p>Agora que a aplicação foi criada, iremos registrá-la com o projeto para que ela seja incluída quando qualquer ferramenta for executada (por exemplo para adicionar models para o banco de dados). Aplicações são registradas adicionando-as à lista <code>INSTALLED_APPS</code> que fica nas configurações do projeto.</p>
+
+<p>Abra o arquivo de configurações do projeto <strong>locallibrary/locallibrary/settings.py</strong> e encontre a definição para a lista <code>INSTALLED_APPS</code>. Agora adicione uma nova linha no fim da lista, como a mostrada em negrito abaixo.</p>
+
+<pre class="brush: bash notranslate">INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+<strong> 'catalog.apps.CatalogConfig', </strong>
+]</pre>
+
+<p>A nova linha especifica o objeto de configuração do aplicativo (<code>CatalogConfig</code>) que foi gerado em <strong>/locallibrary/catalog/apps.py</strong> onde a aplicação foi criada.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Você deve ter notado que existem vários outros <code>INSTALLED_APPS</code> (e <code>MIDDLEWARE</code>, pelo final do arquivo de configuração). Eles permitem suporte para o <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">site de administração do Django</a> e, como resultado,  várias funcionalidades que ele utiliza (incluindo seções, autenticação etc).</p>
+</div>
+
+<h2 id="Especificando_o_Banco_de_Dados">Especificando o Banco de Dados</h2>
+
+<p>Tipicamente, esse é o momento em que você também especifica o  banco de dados que será usado no projeto— faz mais sentido usar o mesmo banco de dados tanto para desenvolvimento quanto para a produção (quando possível), a fim de evitar pequenas diferenças de comportamento. Você pode encontrar mais sobre as outras opções em <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#databases">Databases</a> (Documentação Django).</p>
+
+<p>Usaremos o banco de dados SQLite para este exemplo porque não esperamos ter muito acesso simultâneo em um banco de dados para demonstração, e também porque ele não requer trabalho adicional de configuração! Você pode ver como o banco de dados é configurado em <strong>settings.py</strong> (mais informações estão incluidas abaixo).</p>
+
+<pre class="brush: python notranslate">DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+</pre>
+
+<p>Já que nós estamos usando SQLite, nós não precisamos de nenhum outro passo aqui. Vamos ir em frente!</p>
+
+<h2 id="Outras_configurações_do_projeto">Outras configurações do projeto</h2>
+
+<p>O arquivo <strong>settings.py</strong> também é usado para configurar várias outras definições, mas por ora você provavelmente quer mudar apenas a <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-TIME_ZONE">TIME_ZONE</a> — deve se utilizar uma string padrão da <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">Lista de tz time zones</a> (a coluna TZ na tabela contém os valores que você precisa). Mude seu valor de <code>TIME_ZONE</code> para uma string relativa ao seu fuso-horário, por exemplo:</p>
+
+<pre class="brush: python notranslate">TIME_ZONE = 'America/Sao_Paulo'</pre>
+
+<p>Tem outras duas definições que você não vai mudar agora, mas que deve ficar ciente:</p>
+
+<ul>
+ <li><code>SECRET_KEY</code>. É uma chave secreta que é usada como parte da estratégia de segurança dos websites Django. Se você não está protegendo seu código durante o desenvolvimento, você precisará usar um código diferente (que talvez seja lido de uma variável de ambiente ou arquivo) quando colocar no ambiente de produção.</li>
+ <li><code>DEBUG</code>. Isto habilita a depuração de logs sejam exibidos em um erro ao invés de respostas de status de código HTTP. Isso deve ser definido como <code>False</code> na produção, já que informações de debug são úteis para invasores, mas por enquanto nós manteremos <code>True.</code></li>
+</ul>
+
+<h2 id="Conectando_o_mapeador_de_URL">Conectando o mapeador de URL</h2>
+
+<p>O website foi criado com um arquivo mapeador de URL (<strong>urls.py</strong>) na pasta do projeto. Embora você possa usar esse arquivo para gerenciar todos seus mapeamentos de URL, é mais comum fazer os mapeamentos diretamente no aplicativo associado.</p>
+
+<p>Abra <strong>locallibrary/locallibrary/urls.py</strong> e leia o texto que explica alguma formas de usar o mapeador de URL.</p>
+
+<pre class="brush: python notranslate">"""locallibrary URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/2.0/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+]
+</pre>
+
+<p>Os mapeamentos de URL são gerenciados através da variável <code>urlpatterns</code>  que é uma lista Python de funções <code>path()</code>. Cada função <code>path()</code> associa um padrão de URL para uma <em>view específica</em>, que será exibida quando o padrão for correspondido, ou com outra lista de testes de padrões de URL (no segundo caso, o padrão vem da "URL base" para padrões definidos no módulo target). A lista <code>urlpatterns</code> define inicialmente uma função única que mapeia todas URLs com o padrão admin para o módulo <code>admin.site.urls</code>, que contém as próprias definições de mapeamento de URL da área de administração do aplicativo.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> A rota em <code>path()</code> é uma string que define um padrão de URL para correspondência. Essa string pode incluir um nome de variável (entre tags), e.g. <code>'catalog/&lt;id&gt;/'</code>. Esse padrão corresponderá a uma URL como <strong>/catalog/</strong><em>any_chars</em><strong>/</strong> e passa <em>any_chars</em> para a view como uma string com paramêtros nome <code>id</code>). Nós discutiremos métodos de caminho e padrões de rota ainda mais em tópicos posteriores</p>
+</div>
+
+<p>Adicione as linhas abaixo no fim do arquivo a fim de adicionar um novo item à lista <code>urlpatterns</code>. Esse novo item inclui um  <code>path()</code> que encaminha solicitações com o padrão <code>catalog/</code> para o módulo <code>catalog.urls</code> (o arquivo com a URL relativa <strong>/catalog/urls.py</strong>). </p>
+
+<pre class="brush: python notranslate"># Use include() to add paths from the catalog application
+from django.conf.urls import include
+from django.urls import path
+
+urlpatterns += [
+    path('catalog/', include('catalog.urls')),
+]
+</pre>
+
+<p>Agora iremos mudar a URL raíz de nosso site (i.e. <code>127.0.0.1:8000</code>) para <code>127.0.0.1:8000/catalog/</code>; pois esse é o único app que iremos usar neste projeto. Para isso, usaremos uma função view especial (<code>RedirectView</code>), que leva como primeiro argumento a nova URL relativa para redirecionar para <code>/catalog/</code> quando o padrão URL especificado na função <code>path()</code> for chamado (a URL raíz nesse caso).</p>
+
+<p>Adicione as linhas abaixo, novamente no fim do arquivo:</p>
+
+<pre class="brush: python notranslate">#Add URL maps to redirect the base URL to our application
+from django.views.generic import RedirectView
+urlpatterns += [
+ path('', RedirectView.as_view(url='/catalog/')),
+]</pre>
+
+<p>Deixe o primeiro parâmetro da função path vazio, implicando em '/'. Se você escrever o primeiro parâmetro como '/', Django irá te mostar o seguinte aviso assim que iniciar o servidor de desenvolvimento.</p>
+
+<pre class="brush: python notranslate">System check identified some issues:
+
+WARNINGS:
+?: (urls.W002) Your URL pattern '/' has a route beginning with a '/'.
+Remove this slash as it is unnecessary.
+If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'.
+</pre>
+
+<p>Por padrão, Django não "serve" arquivos estáticos como CSS, JavaScript e imagens, mas ele pode ser útil para o servidor web de desenvolvimento enquanto você cria seu site. Como comentário final sobre o mapeador de URL, você pode habilitar a veiculação de arquivos estáticos durante o desenvolvimento adicionando as seguintes linhas.</p>
+
+<p>Coloque o seguinte bloco no fim do arquivo:</p>
+
+<pre class="notranslate"><code># Use static() to add url mapping to serve static files during development (only)
+from django.conf import settings
+from django.conf.urls.static import static
+
+urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</code>
+</pre>
+
+<div class="note">
+<p><strong>Nota</strong>: Existem várias maneiras de estender a lista <code>urlpatterns</code> (acima nós acrecentamos uma nova lista de itens usando o operador <code>+=</code> para separar claramente o velho do novo código). Poderiamos ter apenas incluído esse novo padrão de mapeamento na definição da lista original.</p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+  path('admin/', admin.site.urls),
+  path('catalog/', include('catalog.urls')),
+ path('', RedirectView.as_view(url='/catalog/', permanent=True)),
+] + <code>static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</code>
+</pre>
+
+<p>Além disso, incluimos a linha para importação (<code>from django.urls import include</code>) com o código que usa-o (que facilita ver o que nós adicionamos), porém, é mais comum incluir todas as linhas de import no topo do arquivo Python.</p>
+</div>
+
+<p>Finalmente, crie um arquivo dentro da pasta catalog e dê o nome <strong>urls.py</strong>, adicione então o seguinte texto para definir um <code>urlpatterns</code> importado (e vazio). É aqui onde você adicionará nossos padrões enquanto desenvolvemos o aplicativo.</p>
+
+<pre class="brush: python notranslate">from django.urls import path
+from catalog import views
+
+
+urlpatterns = [
+
+]
+</pre>
+
+<h2 id="Testando_o_framework_do_site">Testando o framework do site</h2>
+
+<p>Você acabou de criar o escopo do site. Por enquanto o site ainda não faz nada, mas vale a pena testá-lo para garantir que nenhuma de nossas mudanças tenha criado algum problema.</p>
+
+<p>Antes de começarmos, devemos primeiramente executar uma <em>migração de banco de dados</em>. Isso atualiza nosso banco de dados para incluir qualquer model em nossas aplicações instaladas (e remove avisos da build).</p>
+
+<h3 id="Migrando_Bancos_de_Dados">Migrando Bancos de Dados</h3>
+
+<p>Django usa um Object-Relational-Mapper (ORM) que mapeia as definições de  Model no código Django para a estrutura do banco de dados subjacente. Como mudamos nossas definições de model, Django localiza as mudanças e cria scripts para migração de banco de dados (em<strong> /locallibrary/catalog/migrations/</strong>) para migrar automaticamente a estrutura de dados subjacente no banco de dados para manter a correnpondência com o model.</p>
+
+<p>Quando criamos nosso website, Django adicionou automaticamente um número de models para serem usados na área admin do site (que nós veremos depois). Execute os comandos abaixo para definir as tabelas para aqueles models no banco de dados (verifique se você está no diretório que contém o arquivo <strong>manage.py</strong>):</p>
+
+<pre class="brush: bash notranslate">python3 manage.py makemigrations
+python3 manage.py migrate
+</pre>
+
+<div class="warning">
+<p><strong>Importante</strong>: Você precisará executar os comandos acima sempre que alterar seus models de uma forma que afete a estrutura de dados que precisa ser armazenada (incluindo adição e remoção de todos models e campos individuais).</p>
+</div>
+
+<p>O comando <code>makemigrations</code> <em>cria</em> (mas não aplica) as migrações para todos aplicativos instalados em seu projeto (você pode especificar o nome do aplicativo para executar apenas uma migração para um único projeto). Isso te permite checar o código para essas migrações antes delas serem aplicadas — quando você é experiente em Django, você pode escolher ajustá-los um pouco!</p>
+
+<p>O comando <code>migrate</code> aplica as migrações em seu banco de dados (Django rastreia quais foram adicionados ao banco de dados atual).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Leia <a href="https://docs.djangoproject.com/en/2.0/topics/migrations/">Migrations</a> (Documentação Django) para informações adicionais sobre os  comandos de migração menos usados.</p>
+</div>
+
+<h3 id="Testando_o_website">Testando o website</h3>
+
+<p>Durante o desenvolvimento você pode testar o website usando o <em>webserver de desenvolvimento</em>, e vê-lo em seu navegador local.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: O web server de desenvolvimento não tem performance ou desempenho suficiente para uso em produção, mas é uma maneira bem fácil de atualizar seu website Django e utilizá-lo durante o desenvolvimento para conseguir um teste rápido e conveniente. Por padrão, o site é "hospedado" em seu computador local (<code>http://127.0.0.1:8000/)</code>, mas você também pode especificar que outros computadores da rede acessem-o. Para mais informações acesse <a href="https://docs.djangoproject.com/en/2.0/ref/django-admin/#runserver">django-admin and manage.py: runserver</a> (Documentação Django).</p>
+</div>
+
+<p>Execute o <em>web server de desenvolvimento</em> com o comando <code>runserver</code> (no mesmo diretório de <strong>manage.py</strong>):</p>
+
+<pre class="brush: bash notranslate">python3 manage.py runserver
+
+ Performing system checks...
+
+ System check identified no issues (0 silenced).
+ August 15, 2018 - 16:11:26
+ Django version 2.1, using settings 'locallibrary.settings'
+ Starting development server at http://127.0.0.1:8000/
+ Quit the server with CTRL-BREAK.
+</pre>
+
+<p>Com o servidor funcionando, você pode ver seu site colocando o endereço <code>http://127.0.0.1:8000/</code> em seu navegador local. Você deve ver uma página de erro como essa:</p>
+
+<p><img alt="Django Debug page for Django 2.0" src="https://mdn.mozillademos.org/files/15729/django_404_debug_page.png"></p>
+
+<p>Não se assuste! Essa página de erro é esperada, pois nós não temos nehuma página ou url definida no módulo <code>catalogs.urls</code> (que é para onde somos redirecionados quando usamos a URL para a raíz do site).</p>
+
+<div class="note">
+<p><strong>Nota</strong>: A página acima demontra um ótimo recurso do Django — o log de depuração automatizado. Uma tela de erro será exibida com informações referentes ao erro sempre que uma página não consiga ser encontrada, ou caso o código tenha algum erro. Nesse caso poderemos ver que a URL que  nós fornecemos não corresponde a nenhum de nossos padrões de URL (como listado). O log será desativado durante a produção (quando colocamos nosso site online na WEB), nesse caso uma página menos informativa (porém, mais amigável ao usuário) será exibida.</p>
+</div>
+
+<p>No momento basta saber que o Django está funcionando! </p>
+
+<div class="note">
+<p><strong>Nota</strong>: Você deve executar novamente as migrações e testar o site sempre que fizer alguma mudança signifcante. Não demora muito!</p>
+</div>
+
+<h2 id="Desafio">Desafio</h2>
+
+<p>O diretório <strong>catalog/</strong> contém arquivos para views, models, e outras partes da aplicação. Abra esses arquivos e inspecione o bolierplate (códigos incluídos em muitos lugares com pouca ou nenhuma alteração). </p>
+
+<p>Como você viu acima, um mapeamento de URL para o site Admin já foi adicionado no arquivo <strong>urls.py</strong> do projeto. Vá à área do admin em seu navegador e veja o que acontece (você pode deduzir a URL correta para o mapeamento acima).</p>
+
+<h2 id="Sumário">Sumário</h2>
+
+<p>Você acabou de criar um "esqueleto" para websties, agora você pode popular o site com URL's, models, views e templates.</p>
+
+<p>Como o escopo para o <a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">website Local Library</a> está completo e executando, é hora de começar a escrever códigos que farão o website realizar sua função.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.0/intro/tutorial01/">Codificando seu primeiro app Django - parte 1</a>  (Documentação Django)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.0/ref/applications/#configuring-applications">Aplicativos</a> (Documentação Django). Contém informações de como configurar aplicativos.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma biblioteca local</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando o escopo do website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Parte 3: Utilizando models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Parte 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial </a><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Segurança de aplicações Django</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/testing/index.html b/files/pt-br/learn/server-side/django/testing/index.html
new file mode 100644
index 0000000000..19867b2eca
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/testing/index.html
@@ -0,0 +1,944 @@
+---
+title: 'Tutorial Django Parte 10: Testando uma aplicação web Django'
+slug: Learn/Server-side/Django/Testing
+translation_of: Learn/Server-side/Django/Testing
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Forms", "Learn/Server-side/Django/Deployment", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">À medida que websites crescem, eles se tornam mais difíceis de testar manualmente. Não apenas mais para testar, mas, as interações entre componentes tornam-se mais complexas, uma pequena mudança em uma área pode impactar outras áreas, portanto mais mudanças serão necessárias para garantir que tudo permaneça funcionando e erros não sejam introduzidos à medida que mais alterações forem feitas. Uma maneira de mitigar esses problemas é escrever testes automatizados, que podem ser executados facilmente e confiavelmente toda vez que você faz uma alteração. Este tutorial mostra como automatizar testes unitários do seu website utilizando o <em>framework</em> de testes do Django.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Complete todos os tópicos de tutoriais anteriores, incluindo <a href="/en-US/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Entender como escrever testes unitários para websites baseados em Django.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_Geral">Visão Geral</h2>
+
+<p>A <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Local Library</a> atualmente tem páginas para mostrar listas de todos livros e autores, visualização detalhada para itens <code>Book</code> e <code>Author</code>, uma página para renovar <code>BookInstance</code>s, e páginas para criar, atualizar e excluir itens <code>Author</code> (e também registros de <code>Book</code>, se você completou o desafio no <a href="/en-US/docs/Learn/Server-side/Django/Forms">forms tutorial</a>). Mesmo com este site relativamente pequeno, navegar manualmente por cada página e verificar superficialmente se tudo funciona como esperado pode levar vários minutos. À medida que fizemos mudanças e aumentamos o site, o tempo necessário para verificar manualmente se tudo funciona  "devidamente" só aumentará. Se continuássemos como estamos, eventuamente estaríamos gastando a maior parte do tempo testando, e muito pouco tempo aprimorando nosso código.</p>
+
+<p>Testes automatizados podem realmente ajudar com este problema! Os benefícios óbvios são que eles podem ser executados muito mais rápido que testes manuais, podem testar com um nível mais baixo de detalhes, e testa exatamente a mesma funcionalidade (testadores humanos não são nem de longe tão confiáveis!). Por serem rápidos, testes automatizados podem ser executados mais regularmente, e se um teste falhar, eles apontam exatamente para onde o código não está funcionando como esperado .</p>
+
+<p>Além disso, testes automatizados podem atuar como o primeiro "usuário" do mundo real do seu código, forçando você a ser rigoroso ao definir e documentar como seu website deve se comportar. Geralmente, eles são a base para seus exemplos de código e documentação. Por essas razões, alguns processos de desenvolvimento de código iniciam com definição e implementação de teste, o qual após o código é escrito para corresponder ao comportamento necessário (ex. <a href="https://en.wikipedia.org/wiki/Test-driven_development">desenvolvimento guiado por testes</a> e <a href="https://en.wikipedia.org/wiki/Behavior-driven_development">desenvolvimento guiado por comportamento</a>).</p>
+
+<p>Este tutorial mostra como escrever testes automatizados para Django, adicionando um número de testes para o website <em>LocalLibrary</em>.</p>
+
+<h3 id="Tipos_de_teste">Tipos de teste</h3>
+
+<p>Há inúmeros tipos, níveis, e classificações de testes e abordagens de testes. Os testes automatizados mais importantes são:</p>
+
+<dl>
+ <dt>Testes unitários</dt>
+ <dd>Verifica o comportamento funcional de componentes individuais, geralmente ao nível de classe e função.</dd>
+ <dt>Testes de regressão</dt>
+ <dd>Testes que reproduzem erros históricos. Cada teste é executado inicialmente para verificar se o erro foi corrigido, e então executado novamente para garantir que não foi reintroduzido após alterações posteriores no código.</dd>
+ <dt>Testes de integração</dt>
+ <dd>Verifica como agrupamentos de componentes funcionam quando utilizados  juntos. Testes de integração estão cientes das interações necessárias entre componentes, mas não necessariamente das operações internas de cada componente. Eles podem abranger agrupamentos simples de componentes através de todo website.</dd>
+</dl>
+
+<div class="note">
+<p><strong>Nota: </strong>Outros tipos de testes comuns incluem caixa preta (black box), caixa branca (white box), manual, automatizado, canário (canary), fumaça (smoke), conformidade (conformance), aceitação (acceptance), funcional (functional), sistema (system), <em>performance</em>, carga (load) e testes de <em>stress</em>. Procure-os para mais informaçãos.</p>
+</div>
+
+<h3 id="O_que_o_Django_fornece_para_testes">O que o Django fornece para testes?</h3>
+
+<p>Testar um website é uma tarefa complexa, porque isto é composto de várias camadas de lógica – do tratamento de requisições no nível HTTP, consultas de modelos, validação e processamento de formulários, e renderização de <em>template</em>.</p>
+
+<p>Django fornece um <em>framework</em> de teste com uma baixa hierarquia de classes construida na biblioteca padrão <code><a href="https://docs.python.org/3/library/unittest.html#module-unittest" title="(in Python v3.5)">unittest</a></code> de Python. Apesar do nome, este <em>framework</em> de teste é adequado para testes unitários e de integração. O <em>framework</em> Django adiciona métodos e ferramentas de API para ajudar a testar o comportamento web e específico do Django. Isso permite você simular requisições, inserir dados de teste e inspecionar as saídas do seu aplicativo. Django também fornece uma API (<a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#liveservertestcase">LiveServerTestCase</a>) e ferramentas para <a href="https://docs.djangoproject.com/en/2.1/topics/testing/advanced/#other-testing-frameworks">usar diferentes frameworks de teste</a>, por exemplo, você pode integrar com o popular framework <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Selenium</a> para simular um usuário interagindo com um navegador.</p>
+
+<p>Para escrever um teste, você deriva de qualquer uma das classes base de teste de Django (ou <em>unittest</em>) (<a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#simpletestcase">SimpleTestCase</a>, <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#transactiontestcase">TransactionTestCase</a>, <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">TestCase</a>, <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#liveservertestcase">LiveServerTestCase</a>) e então escreve métodos separados para verificar se a funcionalidade específica funciona como esperado (testes usam métodos "<em>assert</em>" para testar se a expressão resulta em valores <code>True</code> ou <code>False</code>, ou se os dois valores são iguais, etc.). Quando você inicia a execução de um teste, o framework executa os métodos de teste escolhidos em suas classes derivadas. Os métodos de teste são executados independentemente, com configuração comum e/ou comportamento <em>tear-down</em> definido na classe, como mostrado abaixo.</p>
+
+<pre class="brush: python notranslate">class YourTestClass(TestCase):
+    def setUp(self):
+  # Setup run before every test method.
+        pass
+
+    def tearDown(self):
+  # Clean up run after every test method.
+        pass
+
+    def test_something_that_will_pass(self):
+        self.assertFalse(False)
+
+    def test_something_that_will_fail(self):
+        self.assertTrue(False)
+</pre>
+
+<p>A melhor classe base para maioria dos testes é <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">django.test.TestCase</a>. Esta classe de teste cria um banco de dados limpo antes dos testes serem executados, e executa todas as funções de teste em sua própria transação. A classe também possui um <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.Client" title="django.test.Client">Client</a> de teste, que você pode utilizar para simular um usuário interagindo com o código no nível de <em>view</em>. Nas seções a seguir vamos nos concentrar nos testes unitários, criados utilizando a classe base <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">TestCase</a>.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> A classe <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">django.test.TestCase</a> é muito conveniente, mas pode resultar em alguns testes mais lentos do que necessitam ser (nem todo teste necessita configurar seu próprio banco de dados ou simular interação de <em>view</em>). Uma vez que esteja familiar com o que você pode fazer com essa classe, você pode querer substituir alguns dos seus testes por classes de teste mais simples disponíveis.</p>
+</div>
+
+<h3 id="O_que_você_deve_testar">O que você deve testar?</h3>
+
+<p>Você deve testar todos aspectos do seu próprio código, mas nenhuma biblioteca ou funcionalidade oferecida como parte do Python ou Django.</p>
+
+<p>Assim por exemplo, conseidere o <em>model</em> <code>Author</code> definido abaixo. Você não precisa testar explicitamente se <code>first_name</code> e <code>last_name</code> foram armazenados corretamente como <code>CharField</code> no banco de dados, porque isso é algo definido pelo Django (embora, é claro, na prática você inevitávelmente testará esta funcionalidade durante o desenvolvimento). Você também não precisa testar se o <code>date_of_birth</code> foi validado para ser um campo de data, porque isso novamente é algo implementeado no Django.</p>
+
+<p>No entanto, você deve verificar o texto utilizado para os <em>labels</em> (<em>First name, Last name, Date of birth, Died</em>), e o tamanho do campo alocado para o texto (<em>100 caracteres</em>), porque isso faz parte do seu <em>design</em> e algo que pode ser violado/alterado no futuro.</p>
+
+<pre class="brush: python notranslate">class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return '%s, %s' % (self.last_name, self.first_name)</pre>
+
+<p>Similarmente, você deve verificar se os métodos personalizados  <code style="font-style: normal; font-weight: normal;">get_absolute_url()</code> e <code style="font-style: normal; font-weight: normal;">__str__()</code> se comportam como desejado, porque els são sua lógica de código/negócios. No caso de <code style="font-style: normal; font-weight: normal;">get_absolute_url()</code> você pode confiar que o método <code>reverse()</code> de Django, foi implementado corretamente, portanto, o que você esta testando é se a <em>view</em> associada foi realmente definida.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Leitores astutos podem notar que também gostariamos de restringir que a data de nascimento e morte como valores sensíveis, e verificar se a morte vem após o nascimento. Em Django, esta restrição seria adicionada a suas classes <em>form</em> (Embora você possa definir validadores para campos do modelo e validadores de modelo, estes só serão usados no nível do formulário se forem chamdos pelo método clean() do model. Isso requer um ModelForm ou o método clean() do modelo precisa ser especificamente chamado).</p>
+</div>
+
+<p>Com isso em mente, vamos começar a ver como definir e executar testes.</p>
+
+<h2 id="Visão_geral_da_estrutura_de_teste">Visão geral da estrutura de teste</h2>
+
+<p>Antes de entrarmos nos detalhes de "o que testar", vamos primeiro examinar brevemente <em>onde</em> e <em>como</em> os testes são definidos.</p>
+
+<p>Django usa o módulo <em>unittest</em> com <a href="https://docs.python.org/3/library/unittest.html#unittest-test-discovery" title="(in Python v3.5)">descoberta de teste acoplada</a>, que descrobrirá testes no diretório de trabalho atual em qualquer arquivo nomeado com o padrão <strong>test*.py</strong>. Fornecido o nome do arquivo adequadamente, você pode usar qualquer estrutura que desejar. Recomendamos que você crie um módulo para seu código de teste, e tenha arquivos separados para <em>models</em>, <em>views</em>, <em>forms </em>e qualquer outro tipo de código que você precise testar. Por exemplo:</p>
+
+<pre class="notranslate">catalog/
+  /tests/
+  __init__.py
+  test_models.py
+  test_forms.py
+  test_views.py
+</pre>
+
+<p>Crie uma estrutura de arquivos como mostrado acima em seu projeto <em>LocalLibrary</em>. O <strong>__init__.py</strong> deve ser um arquivo vazio (isso informa ao Python que o diretório é um pacote). Você pode criar os três arquivos de teste copiando e renomeando o arquivo de teste do "esqueleto" <strong>/catalog/tests.py</strong>.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> O arquivo de teste <strong>/catalog/tests.py</strong> do "esqueleto", foi criado automaticamente quando nós <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">construimos o "esqueleto" do website Django</a>. É perfeitamente "legal" colocar todos seus testes dentro dele, mas se você testar devidamente, você acabará rapidamente com um arquivo de teste muito grande e incontrolável.</p>
+
+<p>Exclua o arquivo do "esqueleto", pois não precisamos dele.</p>
+</div>
+
+<p>Abra <strong>/catalog/tests/test_models.py</strong>. O arquivo deve importar <code>django.test.TestCase</code>, como mostrado:</p>
+
+<pre class="brush: python notranslate">from django.test import TestCase
+
+# Create your tests here.
+</pre>
+
+<p>Frequentemente, você adicionará uma classe de teste para cada <em>model/view/form</em> que deseja testar, com métodos individuais para testar funcionalidades específicas. Em outros casos, você pode desejar ter uma classe separada para testar um caso de uso específico, com funções de teste individuais que testam aspectos desse caso de uso (por exemplo, uma classe para testar se um campo do <em>model</em> é validado corretamente, com funções para testar cada um dos possíveis casos de falha). Novamente, a estrutura depende muito de você, mas é melhor se você for consistente.</p>
+
+<p>Adicione a classe de teste abaixo na parte inferior do arquivo. A classe demonstra como construir uma classe de teste derivando de <code>TestCase</code>.</p>
+
+<pre class="brush: python notranslate">class YourTestClass(TestCase):
+    @classmethod
+    def setUpTestData(cls):
+        print("setUpTestData: Run once to set up non-modified data for all class methods.")
+        pass
+
+    def setUp(self):
+        print("setUp: Run once for every test method to setup clean data.")
+        pass
+
+    def test_false_is_false(self):
+        print("Method: test_false_is_false.")
+        self.assertFalse(False)
+
+    def test_false_is_true(self):
+        print("Method: test_false_is_true.")
+        self.assertTrue(False)
+
+    def test_one_plus_one_equals_two(self):
+        print("Method: test_one_plus_one_equals_two.")
+        self.assertEqual(1 + 1, 2)</pre>
+
+<p>A nova classe define dois métodos que você pode utilizar para aconfiguração de pré-teste (por exemplo, para criar quaisquer modelos ou outros objetos que precisará para to teste):</p>
+
+<ul>
+ <li><code>setUpTestData()</code> é chamado uma vez no início da execução do teste para configuração em nível de classe. Você usaria isso para criar objetos que não serão modificados ou alterados em nenhum dos métodos de teste.</li>
+ <li><code>setUp()</code> é chamado antes de toda função de teste para configurar qualquer objeto que possa ser modificado pelo teste (toda função de teste receberá uma versão "nova" desses objetos).</li>
+</ul>
+
+<div class="note">
+<p>As classes de teste também têm um método <code>tearDown()</code>, que não usamos. Este método não é particularmente útil para testes de banco de dados, pois a classe base <code>TestCase</code> cuida da desmontagem do banco de dados para você.</p>
+</div>
+
+<p>Abaixo desses, temos vários métodos de teste, que usam funções <code>Assert</code> para testar se as condições são verdadeiras, falsas ou iguais (<code>AssertTrue</code>, <code>AssertFalse</code>, <code>AssertEqual</code>). Se a condição não for avaliada como esperado, então o teste falhará e reportará o erro ao seu console.</p>
+
+<p><code>AssertTrue</code>, <code>AssertFalse</code>, <code>AssertEqual</code> são assertivas padrão fornecidas pelo <strong>unittest</strong>. Existem outras assertivas padão no <em>framework</em> e também <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#assertions">Django especifica assertivas</a> para testar se uma <em>view</em> redireciona (<code>assertRedirects</code>), para testar se um template específico foi utilizado (<code>assertTemplateUsed</code>), etc.</p>
+
+<div class="note">
+<p>Você normalmente não deve incluir funções <strong>print()</strong> em seus testes como mostrado acima. Nós fizemos isso aqui apenas para que você posssa ver no console a ordem que as funções de configuração são chamadas (na seção a seguir).</p>
+</div>
+
+<h2 id="Como_executar_os_testes">Como executar os testes</h2>
+
+<p>A maneira mais fácil para executar todos os testes é usar o comando:</p>
+
+<pre class="brush: bash notranslate">python3 manage.py test</pre>
+
+<p>Isso descobrirá todos arquivos nomeados com o padrão <strong>test*.py</strong> no diretório atual e executará todos testes definidos usando as classes base apropriadas (aqui temos vários arquivos de teste, mas, atualmente, apenas  <strong>/catalog/tests/test_models.py</strong> contém testes). Por padrão, os testes irão reportar individualmente apenas falhas no teste, seguidos por um resumo do teste.</p>
+
+<div class="note">
+<p>Se você obter erros semelhantes a: <code>ValueError: Missing staticfiles manifest entry ...</code> isso pode ocorrer porque o teste não é executado como <em>collectstatic</em> por padrão e seu <em>app</em> está usando uma classe de armazenamento que exige isto (veja <a href="https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#django.contrib.staticfiles.storage.ManifestStaticFilesStorage.manifest_strict">manifest_strict</a> para mais informações). Existem várias maneiras de solucionar esse problema - o mais fácil é simplesmente executar <em>collectstatic</em> antes de executar os testes:</p>
+
+<pre class="brush: bash notranslate">python3 manage.py collectstatic
+</pre>
+</div>
+
+<p>Execute os testes no diretório raiz de <em>LocalLibrary</em>. Você deve ver uma saída como a abaixo.</p>
+
+<pre class="brush: bash notranslate">&gt; python3 manage.py test
+
+Creating test database for alias 'default'...
+<strong>setUpTestData: Run once to set up non-modified data for all class methods.
+setUp: Run once for every test method to setup clean data.
+Method: test_false_is_false.
+setUp: Run once for every test method to setup clean data.
+Method: test_false_is_true.
+setUp: Run once for every test method to setup clean data.
+Method: test_one_plus_one_equals_two.</strong>
+.
+======================================================================
+FAIL: test_false_is_true (catalog.tests.tests_models.YourTestClass)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "D:\Github\django_tmp\library_w_t_2\locallibrary\catalog\tests\tests_models.py", line 22, in test_false_is_true
+    self.assertTrue(False)
+AssertionError: False is not true
+
+----------------------------------------------------------------------
+Ran 3 tests in 0.075s
+
+FAILED (failures=1)
+Destroying test database for alias 'default'...</pre>
+
+<p>Aqui vemos que tivemos uma falha no teste e podemos ver exatamente qual função falhou e por quê (essa falha é esperada, porque <code>False</code> não é <code>True</code>!).</p>
+
+<div class="note">
+<p><strong>Dica: </strong>A coisa mais importante para aprender com a saída do teste acima é que é muito mais valioso se você utilizar nomes descritivos/informativos para seus objetos e métodos.</p>
+</div>
+
+<p>O texto acima mostrado em <strong>negrito</strong> normalmente não apareceria na saída do teste (isso é gerado pelas funções <code>print()</code> em nossos teste). Isso mostra como o método  <code>setUpTestData()</code> é chamdo uma vez para classe e <code>setUp()</code> é chamado antes de cada método.</p>
+
+<p>As próximas seções mostram como você pode executar testes específicos e como controlar quanta infromação os testes exibem.</p>
+
+<h3 id="Mostrando_mais_informações_de_teste">Mostrando mais informações de teste</h3>
+
+<p>Se você deseja obter mais informação sobre a execução do teste, você pode mudar  a verbosidade (<em>verbosity)</em>. Por exemplo, para listar os sucessos do teste, bem como as falhas (e um monte de informações sobre como o banco de dados de teste está configurado) vocêpode definir a <em>verbosity</em> para "2" como mostrado:</p>
+
+<pre class="brush: bash notranslate">python3 manage.py test --verbosity 2</pre>
+
+<p>Os níveis permitidos de <em>verbosity</em> são 0, 1, 2, e 3, com o padrão sendo "1".</p>
+
+<h3 id="Executando_testes_específicos">Executando testes específicos</h3>
+
+<p>Se você desseja executar um subconjunto de seus testes, você pode fazer isso especificando o caminho completo para o(s) pacote(s), módulos, subclasse <code>TestCase</code> ou método:</p>
+
+<pre class="brush: bash notranslate"># Run the specified module
+python3 manage.py test catalog.tests
+
+# Run the specified module
+python3 manage.py test catalog.tests.test_models
+
+# Run the specified class
+python3 manage.py test catalog.tests.test_models.YourTestClass
+
+# Run the specified method
+python3 manage.py test catalog.tests.test_models.YourTestClass.test_one_plus_one_equals_two
+</pre>
+
+<h2 id="Testes_da_LocalLibrary">Testes da LocalLibrary</h2>
+
+<p>Agora que sabemos como executar nosso testes e que tipo de coisas precisams testar, vamos ver alguns exemplos práticos.</p>
+
+<div class="note">
+<p><strong>Nota: </strong>Não escreveremos todos os testes possíveis, mas isso deve lhe dar uma ideia de como testes trabalham e o que mais você pode fazer.</p>
+</div>
+
+<h3 id="Models">Models</h3>
+
+<p>Como discutido acima, devemos testar qualquer coisa que faça parte do nosso projeto ou que seja definido por código que escrevemos, mas não bibliotecas/códigos que já foram testados pelo Django ou pela equipe de desenvolvimento do Python.</p>
+
+<p>Por exemplo, considere o <em>model</em> <code>Author</code> abaixo. Aqui devemos testar os <em>labels</em> para todos os campos, porque, embora não tenhamos específicado explicitamente a maioria deles, temos um projeto que diz quais devem ser esses valores. Se não testamos os valores, não sabemos se os <em>labels</em> dos campos  têm os valores pretendidos. Similarmente, enquanto confiamos que o Django criará um campo com o tamanho específicado, vale a pena específicar um teste para este tamanho, para garantir que ele foi implementado como planejado.</p>
+
+<pre class="brush: python notranslate">class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return f'{self.last_name}, {self.first_name}'</pre>
+
+<p>Abra nosso <strong>/catalog/tests/test_models.py</strong>, e substitua qualquer código existente pelo seguinte código de teste para o <em>model</em> <code>Author</code>.</p>
+
+<p>Aqui você verá que primeiro importamos <code>TestCase</code> e derivamos nossa classe de teste (<code>AuthorModelTest</code>) a partir dela, usando um nome descritivo para que possamos identificar facilmente quaiquer testes com falha na saída do teste. Nós então chamamos <code>setUpTestData()</code> para criar um objeto autor que iremos usar mas não modificaremos em nenhum dos testes.</p>
+
+<pre class="brush: python notranslate">from django.test import TestCase
+
+from catalog.models import Author
+
+class AuthorModelTest(TestCase):
+ @classmethod
+ def setUpTestData(cls):
+ # Set up non-modified objects used by all test methods
+ Author.objects.create(first_name='Big', last_name='Bob')
+
+ def test_first_name_label(self):
+ author = Author.objects.get(id=1)
+ field_label = author._meta.get_field('first_name').verbose_name
+ self.assertEquals(field_label, 'first name')
+
+ def test_date_of_death_label(self):
+ author=Author.objects.get(id=1)
+ field_label = author._meta.get_field('date_of_death').verbose_name
+ self.assertEquals(field_label, 'died')
+
+ def test_first_name_max_length(self):
+ author = Author.objects.get(id=1)
+ max_length = author._meta.get_field('first_name').max_length
+ self.assertEquals(max_length, 100)
+
+ def test_object_name_is_last_name_comma_first_name(self):
+ author = Author.objects.get(id=1)
+ expected_object_name = f'{author.last_name}, {author.first_name}'
+ self.assertEquals(expected_object_name, str(author))
+
+ def test_get_absolute_url(self):
+ author = Author.objects.get(id=1)
+ # This will also fail if the urlconf is not defined.
+ self.assertEquals(author.get_absolute_url(), '/catalog/author/1')</pre>
+
+<p>Os testes de campo verificam se os valores dos <em>labels</em> dos campos (<code>verbose_name</code>)  e se o tamanho dos campos de caracteres são como esperado. Todos esses métodos possuem nomes descritivos e seguem o mesmo padrão:</p>
+
+<pre class="brush: python notranslate"># Get an author object to test
+author = Author.objects.get(id=1)
+
+# Get the metadata for the required field and use it to query the required field data
+field_label = author._meta.get_field('first_name').verbose_name
+
+# Compare the value to the expected result
+self.assertEquals(field_label, 'first name')</pre>
+
+<p>As coisas interessantes a serem observadas aqui:</p>
+
+<ul>
+ <li>Não podemos obter <code>verbose_name</code> diretamente utilizando  <code>author.first_name.verbose_name</code>, porque <code>author.first_name</code> é uma <em>string</em> (não um identificador para o objeto <code>first_name</code> que podemos utilizar para acessar suas propriedades). Em vez disso, precisamos utilizar o atributo <code>_meta</code> de <em>author</em> para obter uma instância do campo e usá-la para consultar informações adicionais.</li>
+ <li>Optamos por utilizar <code>assertEquals(field_label,'first name')</code> em vez de <code>assertTrue(field_label == 'first name')</code>. A razão para isso é que, se o teste falhar a saída do primeiro informa o que realmente era o <em>label</em>, que torna a depuração do problema um pouco mais fácil.</li>
+</ul>
+
+<div class="note">
+<p><strong>Nota:</strong> Testes para os rótulos <code>last_name</code> e <code>date_of_birth</code> e também para o teste para o tamanho do <code>last_name</code> field foram omitidos. Adicione suas próprias versões agora, seguindo as convenções de nomeclatura e abordagens mostradas acima.</p>
+</div>
+
+<p>Também precisamos testar nossos métodos personalizados. Eles, essencialmente, apenas verificam se o nome do objeto foi construido como esperamos, usando o formato "Last Name", "First Name", e se a URL que obtemos para um item de <code>Author</code> é o que esperávamos.</p>
+
+<pre class="brush: python notranslate">def test_object_name_is_last_name_comma_first_name(self):
+    author = Author.objects.get(id=1)
+    expected_object_name = f'{author.last_name}, {author.first_name}'
+    self.assertEquals(expected_object_name, str(author))
+
+def test_get_absolute_url(self):
+    author = Author.objects.get(id=1)
+    # This will also fail if the urlconf is not defined.
+    self.assertEquals(author.get_absolute_url(), '/catalog/author/1')</pre>
+
+<p>Execute os testes agora. Se você criou o modelo Author como descrevemos no tutorial de modelos, é bem provável que você obtenha um erro para o <em>label</em> <code>date_of_death</code> como mostrado abaixo. O teste está falhando porque foi escrito esperando que a definição do <em>label</em> siga a convenção do Django de não colocar em maíúscula a primeira letra do <em>label</em> (Django faz isso por você).</p>
+
+<pre class="brush: bash notranslate">======================================================================
+FAIL: test_date_of_death_label (catalog.tests.test_models.AuthorModelTest)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+ File "D:\...\locallibrary\catalog\tests\test_models.py", line 32, in test_date_of_death_label
+ self.assertEquals(field_label,'died')
+AssertionError: 'Died' != 'died'
+- Died
+? ^
++ died
+? ^</pre>
+
+<p>Este é um bug muito pequeno, mas destaca como a escrita de testes pode verificar mais minuciosamente quaislquer suposições que você tenha feito.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Altere o <em>label</em> para o campo date_of_death (/catalog/models.py) para "died" e re-executes os testes.</p>
+</div>
+
+<p>Os padrões para testar os outros modelos são semelhantes, portanto não continuaremos discutindo mais isso. Sinta-se livre para criar seus próprios testes para nossos outros modelos.</p>
+
+<h3 id="Forms">Forms</h3>
+
+<p>A filosofia para testar seus <em>forms </em>é a mesma que para testar seus <em>models</em>; você precisa testar qualquer coisa que tenha codificado ou seu projeto especifica, mas não o comportamento do framework subjacente e outras bibliotecas de terceiros</p>
+
+<p>Geralmente, isso significa que você deve testar se os <em>forms</em> têm os campos que você deseja e se esses são exibidos com os <em>labels</em>  e texto de ajuda apropriados. Você não precisa verificar se o Django o tipo de campo corretamente (a menos que você tenha criado seu próprio campo e validação personalizados) — ex. você não precisa testar se um campo de email aceita apenas email. No entanto,  você precisaria testar qualquer validação adicional que você espera que seja executada nos campos e quaisquer mensagens que seu código irá gerar para erros.</p>
+
+<p>Considere nosso <em>form</em> para renovação de livros. Ele tem apenas um campo para data de renovação, que terá um <em>label</em> e um texto de ajuda que precisaremos verificar.</p>
+
+<pre class="brush: python notranslate">class RenewBookForm(forms.Form):
+ """Form for a librarian to renew books."""
+ renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+ def clean_renewal_date(self):
+ data = self.cleaned_data['renewal_date']
+
+ # Check if a date is not in the past.
+ if data &lt; datetime.date.today():
+ raise ValidationError(_('Invalid date - renewal in past'))
+
+ # Check if date is in the allowed range (+4 weeks from today).
+ if data &gt; datetime.date.today() + datetime.timedelta(weeks=4):
+ raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+ # Remember to always return the cleaned data.
+ return data</pre>
+
+<p>Abra nosso arquivo <strong>/catalog/tests/test_forms.py</strong> e substitua qualquer código existente pelo seguinte código de teste para o <em>form</em> <code>RenewBookForm</code>. Nós iniciamos importando nosso <em>form</em> e algumas bibliotecas Python e Django para ajudar testar funcionalidades relacionadas ao tempo. Em seguida, declaramos nossa classe de teste do <em>form,</em> da mesma maneira que fizemos para <em>models</em>,  usando um nome descritivo para a classe de teste derivada de <code>TestCase</code>.</p>
+
+<pre class="brush: python notranslate">import datetime
+
+from django.test import TestCase
+from django.utils import timezone
+
+from catalog.forms import RenewBookForm
+
+class RenewBookFormTest(TestCase):
+    def test_renew_form_date_field_label(self):
+        form = RenewBookForm()
+        self.assertTrue(form.fields['renewal_date'].label == None or form.fields['renewal_date'].label == 'renewal date')
+
+    def test_renew_form_date_field_help_text(self):
+        form = RenewBookForm()
+        self.assertEqual(form.fields['renewal_date'].help_text, 'Enter a date between now and 4 weeks (default 3).')
+
+    def test_renew_form_date_in_past(self):
+        date = datetime.date.today() - datetime.timedelta(days=1)
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertFalse(form.is_valid())
+
+    def test_renew_form_date_too_far_in_future(self):
+        date = datetime.date.today() + datetime.timedelta(weeks=4) + datetime.timedelta(days=1)
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertFalse(form.is_valid())
+
+    def test_renew_form_date_today(self):
+        date = datetime.date.today()
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertTrue(form.is_valid())
+
+    def test_renew_form_date_max(self):
+        date = timezone.localtime() + datetime.timedelta(weeks=4)
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertTrue(form.is_valid())
+</pre>
+
+<p>As primeiras duas funções testam se os campos <code>label</code> e <code>help_text</code> são como esperados. Temos que acessar o campo usando o dicionário de campos (ex. <code>form.fields['renewal_date']</code>). Observe aqui que também precisamos testar se o valor do <em>label</em> é <code>None</code>, porque mesmo que o Django processe o <em>label</em> correto, retornará <code>None</code> se o valor não estiver definido explicitamente.</p>
+
+<p>O restante das funções testam se o form é valido para datas de renovação dentro do intervalo aceitável e inválido para os valores foram do intervalo. Observe como construimos os valores teste de data em torno de nossa data atual (<code>datetime.date.today()</code>) usando <code>datetime.timedelta()</code> (nesse caso, especificando um número de dias ou semanas). Então, apenas criamos o <em>form</em>, passando nossos dados e testando se é válido.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Aqui, na realidade, não usamos o banco de dados ou cliente teste. Considere modificar essses testes para utilizar <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.SimpleTestCase">SimpleTestCase</a>.</p>
+
+<p>Também precisamos validar que os erros corretos sejam gerados se o form é inválido, no entanto, isso geralmente é feito no processamento da view, portanto trataremos disso na próxima seção.</p>
+</div>
+
+<p>Isso é tudo para <em>forms</em>; nós temos alguns outros, mas eles são automaticamente criados pelas nossas <em>views</em> de edição baseada na classe genérica, e devem ser testadas lá! Execute os testes e confirme  se nosso código ainda passa!</p>
+
+<h3 id="Views">Views</h3>
+
+<p>Para validar o comportamento das nossas <em>views</em>, utilzamos <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.Client">Client</a> de teste do Django. Essa classe funciona como um navegador web fictício que podemos usar para simular requisições <code>GET</code> and <code>POST</code> em uma URL e observar a resposta. Podemos ver quase tudo sobre a resposta, desde HTTP de baixo nível (cabeçalhos de resultados e códigos de status) até o <em>template</em> que estamos utilizando para renderizar o HTML e os dados de contexto que estamos passando para ele. Também podemos ver a cadeia de redirecionamentos (se houver) e verificar a URL e o código de status em cada etapa. Isso nos permite verificar se cada <em>view</em> esta fazendo o que é esperado.</p>
+
+<p>Vamos iniciar com uma de nossas <em>views</em> mais simples, que fornece uma lista de todos Autores. Isso é exibido na URL <strong>/catalog/authors/</strong> (uma URL chamada 'authors' na configuração de URL).</p>
+
+<pre class="brush: python notranslate">class AuthorListView(generic.ListView):
+ model = Author
+ paginate_by = 10
+</pre>
+
+<p>Como esta é uma <em>list view</em> genérica, quase tudo é feito para nós pelo Django. Provavelmente, se você confia no Django, então a única coisa que você precisa testar é se a <em>view</em> é acessível na URL correta e pode ser acessada usando seu nome. No entanto, se você está usando um desenvolvimento orientado a testes, você iniciará escrevendo testes que confirmam que a <em>view</em> exibe todos Autores, paginando-os em lotes de 10.</p>
+
+<p>Abra o arquivo <strong>/catalog/tests/test_views.py</strong> e substitua qualquer texto existente pelo seguinte código de teste para <code>AuthorListView</code>. Como antes, importamos nosso <em>model</em> e algumas classe úteis. No método <code>setUpTestData()</code> configuramos vários objetos <code>Author</code> para que possamos testar nossa paginação.</p>
+
+<pre class="brush: python notranslate">from django.test import TestCase
+from django.urls import reverse
+
+from catalog.models import Author
+
+class AuthorListViewTest(TestCase):
+    @classmethod
+    def setUpTestData(cls):
+        # Create 13 authors for pagination tests
+        number_of_authors = 13
+
+        for author_id in range(number_of_authors):
+            Author.objects.create(
+ first_name=f'Christian {author_id}',
+ last_name=f'Surname {author_id}',
+ )
+
+    def test_view_url_exists_at_desired_location(self):
+        response = self.client.get('/catalog/authors/')
+        self.assertEqual(response.status_code, 200)
+
+    def test_view_url_accessible_by_name(self):
+        response = self.client.get(reverse('authors'))
+        self.assertEqual(response.status_code, 200)
+
+    def test_view_uses_correct_template(self):
+        response = self.client.get(reverse('authors'))
+        self.assertEqual(response.status_code, 200)
+        self.assertTemplateUsed(response, 'catalog/author_list.html')
+
+    def test_pagination_is_ten(self):
+        response = self.client.get(reverse('authors'))
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue('is_paginated' in response.context)
+        self.assertTrue(response.context['is_paginated'] == True)
+        self.assertTrue(len(response.context['author_list']) == 10)
+
+    def test_lists_all_authors(self):
+        # Get second page and confirm it has (exactly) remaining 3 items
+        response = self.client.get(reverse('authors')+'?page=2')
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue('is_paginated' in response.context)
+        self.assertTrue(response.context['is_paginated'] == True)
+        self.assertTrue(len(response.context['author_list']) == 3)</pre>
+
+<p>Todos os teste usam o cliente (pertenecente a nossa classe derivada <code>TestCase</code>'s) para simular uma requisição <code>GET</code> e obter uma resposta. A primeira versão verifica uma URL específica URL (observe, apenas o caminho específico, sem o domínio), enquanto a segunda gera a URL  a partir do seu nome na configuração da URL.</p>
+
+<pre class="brush: python notranslate">response = self.client.get('/catalog/authors/')
+response = self.client.get(reverse('authors'))
+</pre>
+
+<p>Uma vez que temos a resposta, consultamos o seu código de status, o <em>template</em> usado, se a resposta é paginada ou não, o número de itens retonado e o número total de itens.</p>
+
+<div class="blockIndicator note">
+<p class="brush: python">Nota: Se você definir a variável <code>paginate_by</code> em seu arquivo  <strong>/c</strong><strong>atalog/views.py</strong> para um número diferente de 10, atualize as linhas que testam se o número correto de itens é exibido nos <em>templates</em> paginados acima e nas seções seguintes. Por exemplo, se você definiu a variável para a lista de autor para 5, atualize a linha acima para:</p>
+
+<pre class="brush: python notranslate">self.assertTrue(len(response.context['author_list']) == 5)
+</pre>
+</div>
+
+<p>A variável mais importante que demonstramos acima é <code>response.context</code>, que é a variável de contexto passada para o <em>template</em> pela <em>view</em>. Isso é incrivelmente útil para testes, porque permite confirmar que nosso template está obtendo todos os dados necessários. Em outras palavras, podemos verificar se estamos utilizando o <em>template</em> pretendido e quais dados o <em>template</em> está obtendo, o que ajuda bastante a verificar que alguns problemas de renderização são apenas devido ao <em>template</em>.</p>
+
+<h4 id="Views_restritas_a_usuários_logados"><em>Views</em> restritas a usuários logados</h4>
+
+<p>Em alguns casos, você desejará testar uma <em>view</em> que é restrita apenas aos usuários logados. Por exemplo, nossa <code>LoanedBooksByUserListView</code> é muito similar a nossa <em>view</em> anterior, mas está disponível apenas para usuários logados e exibe apenas os registros <code>BookInstance</code> que são emprestados pelo usuário atual, têm o status 'emprestado' e são ordenados "mais antigos primeiro".</p>
+
+<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin
+
+class LoanedBooksByUserListView(LoginRequiredMixin, generic.ListView):
+ """Generic class-based view listing books on loan to current user."""
+ model = BookInstance
+ template_name ='catalog/bookinstance_list_borrowed_user.html'
+ paginate_by = 10
+
+ def get_queryset(self):
+ return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')</pre>
+
+<p>Adicione o código seguinte ao <strong>/catalog/tests/test_views.py</strong>. Aqui, primeiro usamos <code>SetUp()</code> para criar alguma contas de login de usuário e objetos <code>BookInstance</code> (junto com seus livros associados e outros registros) que usaremos posteriormente nos testes. Metade dos livros são emprestados para cada usuário teste, mas inicialmente definimos o status de todos os livros como  "manutenção". Usamos <code>SetUp()</code> em vez de <code>setUpTestData()</code> porque modificaremos alguns desses objetos depois.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> O código <code>setUp()</code> abaixo, cria um livro com uma  <code>Language</code> especificada, mas seu código pode não incluir o <em>model</em> <code>Language</code>, pois foi criado como um desafio. Se esse for o caso, simplesmente comente as partes do código que cria ou importa objetos <em>Language</em>. Você também deve fazer isso na seção  <code>RenewBookInstancesViewTest</code> a seguir.</p>
+</div>
+
+<pre class="brush: python notranslate">import datetime
+
+from django.utils import timezone
+from django.contrib.auth.models import User # Required to assign User as a borrower
+
+from catalog.models import BookInstance, Book, Genre, Language
+
+class LoanedBookInstancesByUserListViewTest(TestCase):
+    def setUp(self):
+        # Create two users
+        test_user1 = User.objects.create_user(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+
+ test_user1.save()
+        test_user2.save()
+
+        # Create a book
+        test_author = Author.objects.create(first_name='John', last_name='Smith')
+        test_genre = Genre.objects.create(name='Fantasy')
+        test_language = Language.objects.create(name='English')
+        test_book = Book.objects.create(
+ title='Book Title',
+ summary='My book summary',
+ isbn='ABCDEFG',
+ author=test_author,
+ language=test_language,
+ )
+
+ # Create genre as a post-step
+        genre_objects_for_book = Genre.objects.all()
+  test_book.genre.set(genre_objects_for_book) # Direct assignment of many-to-many types not allowed.
+        test_book.save()
+
+        # Create 30 BookInstance objects
+        number_of_book_copies = 30
+        for book_copy in range(number_of_book_copies):
+            return_date = timezone.localtime() + datetime.timedelta(days=book_copy%5)
+            the_borrower = test_user1 if book_copy % 2 else test_user2
+            status = 'm'
+            BookInstance.objects.create(
+ book=test_book,
+ imprint='Unlikely Imprint, 2016',
+ due_back=return_date,
+ borrower=the_borrower,
+ status=status,
+ )
+
+    def test_redirect_if_not_logged_in(self):
+        response = self.client.get(reverse('my-borrowed'))
+        self.assertRedirects(response, '/accounts/login/?next=/catalog/mybooks/')
+
+    def test_logged_in_uses_correct_template(self):
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('my-borrowed'))
+
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        # Check we used correct template
+        self.assertTemplateUsed(response, 'catalog/bookinstance_list_borrowed_user.html')
+</pre>
+
+<p>Para verificar se a <em>view</em> será redirecionada para uma página de login se o usuário não estiver logado, usamos <code>assertRedirects</code>, como demonstrado em <code>test_redirect_if_not_logged_in()</code>. Para verificar se a página é exibida para um usuário logado, primeiro logamos com nosso usuário teste e então acessamos a página novamente e verificamos se obtivemos um <code>status_code</code> de 200 (successo). </p>
+
+<p>O restante dos testes verificam se nossa <em>view</em> retorna apenas livros emprestados ao nosso usuário atual. Copie o código abaixo e cole no final da classe de teste acima.</p>
+
+<pre class="brush: python notranslate">    def test_only_borrowed_books_in_list(self):
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('my-borrowed'))
+
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        # Check that initially we don't have any books in list (none on loan)
+        self.assertTrue('bookinstance_list' in response.context)
+        self.assertEqual(len(response.context['bookinstance_list']), 0)
+
+        # Now change all books to be on loan
+        books = BookInstance.objects.all()[:10]
+
+        for book in books:
+            book.status = 'o'
+            book.save()
+
+        # Check that now we have borrowed books in the list
+        response = self.client.get(reverse('my-borrowed'))
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        self.assertTrue('bookinstance_list' in response.context)
+
+        # Confirm all books belong to testuser1 and are on loan
+        for bookitem in response.context['bookinstance_list']:
+            self.assertEqual(response.context['user'], bookitem.borrower)
+            self.assertEqual('o', bookitem.status)
+
+    def test_pages_ordered_by_due_date(self):
+        # Change all books to be on loan
+        for book in BookInstance.objects.all():
+            book.status='o'
+            book.save()
+
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('my-borrowed'))
+
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        # Confirm that of the items, only 10 are displayed due to pagination.
+        self.assertEqual(len(response.context['bookinstance_list']), 10)
+
+        last_date = 0
+        for book in response.context['bookinstance_list']:
+            if last_date == 0:
+                last_date = book.due_back
+            else:
+ self.assertTrue(last_date &lt;= book.due_back)
+                last_date = book.due_back</pre>
+
+<p>Você também pode adicionar testes de paginação, se desejar!</p>
+
+<h4 id="Testando_views_com_forms">Testando <em>views</em> com <em>forms</em></h4>
+
+<p>Testar views com forms é um pouco mais complicado que nos casos acima, porque você precisa testar mais caminhos de código: exibição inicial, exibição após falha de validação de dados e exibição após validação com sucesso. A boa notícia é que usamos o cliente para testar quase exatamente da mesma maneira que fizemos para <em>views</em> somente de exibição.</p>
+
+<p>Para demonstrar, vamos escrever alguns testes para a <em>view</em> usada para renovar livros (<code>renew_book_librarian()</code>):</p>
+
+<pre class="brush: python notranslate">from catalog.forms import RenewBookForm
+
+@permission_required('catalog.can_mark_returned')
+def renew_book_librarian(request, pk):
+    """View function for renewing a specific BookInstance by librarian."""
+    book_instance = get_object_or_404(BookInstance, pk=pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        book_renewal_form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_instance.due_back = form.cleaned_data['renewal_date']
+            book_instance.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed'))
+
+    # If this is a GET (or any other method) create the default form
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        book_renewal_form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
+
+ context = {
+ 'book_renewal_form': book_renewal_form,
+ 'book_instance': book_instance,
+ }
+
+    return render(request, 'catalog/book_renew_librarian.html', context)</pre>
+
+<p>Precisamos testar se a <em>view</em> está disponível apenas para usuários que têm a permissão <code>can_mark_returned </code>, e se eles são direcionados para uma página de erro HTTP 404 se tentarem renovar um <code>BookInstance</code> que não existe. Devemos verificar se o valor inicial do form é propagado com uma data três semanas no futuro e se a validação for bem sucedida somos redirecionados para a <em>view</em> "all-borrowed books". Como parte da verificação dos testes de falha de validação, também verificaremos se nosso <em>form</em> está enviando mensagens de erro apropriadas.</p>
+
+<p>Adicione a primeira parte da classe de teste (mostrada abaixo) na parte inferior de <strong>/catalog/tests/test_views.py</strong>. Isso cria dois usuários e duas instâncias de livro, mas apenas concede a um usuário a permissão necessária para acessar a <em>view</em>. O código para conceder permissões durante os testes é mostrado em negrito:</p>
+
+<pre class="brush: python notranslate">import uuid
+
+from django.contrib.auth.models import Permission # Required to grant the permission needed to set a book as returned.
+
+class RenewBookInstancesViewTest(TestCase):
+ def setUp(self):
+ # Create a user
+ test_user1 = User.objects.create_user(username='testuser1', password='1X&lt;ISRUkw+tuK')
+ test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+
+ test_user1.save()
+ test_user2.save()
+
+<strong> permission = Permission.objects.get(name='Set book as returned')
+ test_user2.user_permissions.add(permission)
+ test_user2.save()</strong>
+
+ # Create a book
+ test_author = Author.objects.create(first_name='John', last_name='Smith')
+ test_genre = Genre.objects.create(name='Fantasy')
+ test_language = Language.objects.create(name='English')
+ test_book = Book.objects.create(
+ title='Book Title',
+ summary='My book summary',
+ isbn='ABCDEFG',
+ author=test_author,
+ language=test_language,
+ )
+
+ # Create genre as a post-step
+ genre_objects_for_book = Genre.objects.all()
+ test_book.genre.set(genre_objects_for_book) # Direct assignment of many-to-many types not allowed.
+ test_book.save()
+
+ # Create a BookInstance object for test_user1
+ return_date = datetime.date.today() + datetime.timedelta(days=5)
+ self.test_bookinstance1 = BookInstance.objects.create(
+ book=test_book,
+ imprint='Unlikely Imprint, 2016',
+ due_back=return_date,
+ borrower=test_user1,
+ status='o',
+ )
+
+ # Create a BookInstance object for test_user2
+ return_date = datetime.date.today() + datetime.timedelta(days=5)
+ self.test_bookinstance2 = BookInstance.objects.create(
+ book=test_book,
+ imprint='Unlikely Imprint, 2016',
+ due_back=return_date,
+ borrower=test_user2,
+ status='o',
+ )</pre>
+
+<p>Adicione os seguintes testes na parte inferior da classe de teste. Eles verificam se apenas usuários com a permissão correta (testuser2) podem aceesar a <em>view</em>. Verificamos todos os casos: quando o usuários não está logado, quando um usuário está logado mas não tem as permissões corretas, quando o usuário possui permissões, mas não é o tomador do empréstimo (deve ter êxito), e o que acontece quando eles tentam acessar uma <code>BookInstance</code> que não existe. Também verificamos se o <em>template</em> correto é utilizado.</p>
+
+<pre class="brush: python notranslate"> def test_redirect_if_not_logged_in(self):
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        # Manually check redirect (Can't use assertRedirect, because the redirect URL is unpredictable)
+        self.assertEqual(response.status_code, 302)
+        self.assertTrue(response.url.startswith('/accounts/login/'))
+
+    def test_redirect_if_logged_in_but_not_correct_permission(self):
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        self.assertEqual(response.status_code, 403)
+
+    def test_logged_in_with_permission_borrowed_book(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance2.pk}))
+
+        # Check that it lets us login - this is our book and we have the right permissions.
+        self.assertEqual(response.status_code, 200)
+
+    def test_logged_in_with_permission_another_users_borrowed_book(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+
+        # Check that it lets us login. We're a librarian, so we can view any users book
+        self.assertEqual(response.status_code, 200)
+
+    def test_HTTP404_for_invalid_book_if_logged_in(self):
+ # unlikely UID to match our bookinstance!
+        test_uid = uuid.uuid4()
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk':test_uid}))
+        self.assertEqual(response.status_code, 404)
+
+    def test_uses_correct_template(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        self.assertEqual(response.status_code, 200)
+
+        # Check we used correct template
+        self.assertTemplateUsed(response, 'catalog/book_renew_librarian.html')
+</pre>
+
+<p>Adicione o próximo método de teste, como mostrado abaixo. Isso verifica se a data inicial para o form é três semanas no futuro. Observe como podemos acessar o valor do valor inicial do campo do form (mostrado em negrito).</p>
+
+<pre class="brush: python notranslate">    def test_form_renewal_date_initially_has_date_three_weeks_in_future(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        self.assertEqual(response.status_code, 200)
+
+        date_3_weeks_in_future = datetime.date.today() + datetime.timedelta(weeks=3)
+        self.assertEqual(response<strong>.context['form'].initial['renewal_date']</strong>, date_3_weeks_in_future)
+</pre>
+
+<div class="warning">
+<p>Se você usar a classe <em>form</em> <code>RenewBookModelForm(forms.ModelForm)</code> em vez da classe <code>RenewBookForm(forms.Form)</code>, então o nome do campo do <em>form</em> será <strong>'due_back' </strong>em vez de <strong>'renewal_date'</strong>.</p>
+</div>
+
+<p>O próximo teste (adicione isso a classe também) verifica se a <em>view</em> redireciona para uma lista de todos livros emprestados, se a renovação for bem-sucedida. O que difere aqui é que pela primeira vez mostramos como você pode fazer <code>POST</code> de dados usando o cliente. Os dados do <em>post</em> são o segundo argumento da função <em>post</em>, e são especificados como um dicionário de chave/valores.</p>
+
+<pre class="brush: python notranslate">    def test_redirects_to_all_borrowed_book_list_on_success(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        valid_date_in_future = datetime.date.today() + datetime.timedelta(weeks=2)
+        <strong>response = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':valid_date_in_future})</strong>
+        self.assertRedirects(response, reverse('all-borrowed'))
+</pre>
+
+<div class="warning">
+<p>A view <em>all-borrowed</em> foi adicionada como um <em>desafio</em>, e seu código pode, em vez disso, direcionar para a página inicial '/'. Nesse caso, modifique as últimas duas linhas do código de teste para que sejam como o código abaixo. O <code>follow=True</code> na solicitação, garante que a solicitação retorna a URL final de destino (portanto verifique <code>/catalog/</code> em vez de <code>/</code>).</p>
+
+<pre class="brush: python notranslate"> response = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':valid_date_in_future}, <strong>follow=True</strong> )
+ <strong>self.assertRedirects(</strong><strong>response, '/catalog/')</strong></pre>
+</div>
+
+<p>Copie as última duas funções para a classe, como visto abaixo. Elas testam novamente as requisições <code>POST</code>, mas nesse caso, com datas inválidas de renovação. Utilizamos <code>assertFormError()</code> para verificar se as mensagens de erro são as esperadas.</p>
+
+<pre class="brush: python notranslate">    def test_form_invalid_renewal_date_past(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        date_in_past = datetime.date.today() - datetime.timedelta(weeks=1)
+        response = self.client.post(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}), {'renewal_date': date_in_past})
+        self.assertEqual(response.status_code, 200)
+        <strong>self.assertFormError(</strong><strong>response, 'form', 'renewal_date', 'Invalid date - renewal in past')</strong>
+
+    def test_form_invalid_renewal_date_future(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        invalid_date_in_future = datetime.date.today() + datetime.timedelta(weeks=5)
+        response = self.client.post(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}), {'renewal_date': invalid_date_in_future})
+        self.assertEqual(response.status_code, 200)
+        <strong>self.assertFormError(</strong><strong>response, 'form', 'renewal_date', 'Invalid date - renewal more than 4 weeks ahead')</strong>
+</pre>
+
+<p>Os mesmos tipos de técnicas podem ser usadas para testar a outra <em>view</em>.</p>
+
+<h3 id="Templates"><em>Templates</em></h3>
+
+<p>Django fornece APIs de teste para verificar se o template correto esta sendo chamado por suas views, e para permitir que você verifique se a informação correta está sendo enviada. Entretanto, não há suporte específico à API para testar no Django que sua saída HTML seja renderizada conforme esperado.</p>
+
+<h2 id="Outras_ferramentas_de_teste_recomendadas">Outras ferramentas de teste recomendadas</h2>
+
+<p>O framework de teste do Django pode ajudar você a escrever eficazes testes unitários e de integração — nós apenas arranhamos a superfície do que o framework <strong>unittest</strong> pode fazer, muito menos as adições de Django (por exemplo, confira como você pode usar <a href="https://docs.python.org/3.5/library/unittest.mock-examples.html">unittest.mock</a> para corrigir bibliotecas de terceiros para que você possa testar mais detalhadamente seu próprio código).</p>
+
+<p>Embora existam inúmeras outras ferramentas de teste que você pode utilizar, destacaremos apenas duas:</p>
+
+<ul>
+ <li><a href="http://coverage.readthedocs.io/en/latest/">Coverage</a>: Essa ferramenta Python reporta quando do seu código é realmente executado pelos seus testes. É particularmente útil quando você começando e está tentando descobrir o que exatamente deve testar.</li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Selenium</a> é um framework para automatizar testes em um navegador real. Ele permite simular um usuário real interagindo com o site e fornece uma excelente estrutura para o sistema testar seu site (a próxima etapa do teste de integração).</li>
+</ul>
+
+<h2 id="Desafie-se">Desafie-se</h2>
+
+<p>Existem muito mais <em>models</em> e <em>views</em> que podemos testar. Como uma tarefa simples, tente criar um caso de teste para a <em>view</em> <code>AuthorCreate</code>.</p>
+
+<pre class="brush: python notranslate">class AuthorCreate(PermissionRequiredMixin, CreateView):
+ model = Author
+ fields = '__all__'
+ initial = {'date_of_death':'12/10/2016'}
+ permission_required = 'catalog.can_mark_returned'</pre>
+
+<p>Lembre-se de que você precisa verificar qualquer coisa que você especificar ou que faça parte do projeto. Isso incluirá quem tem acesso, a data inicial, o <em>template</em> utilizado e para onde a view é redirecionada quando bem-sucedida.</p>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Escrever código de teste não é divertido nem glamuroso, e é consequentemente muitas vezes deixado por último (ou nem isso) ao criar um site. No entanto, é uma parte essencial para garantir que seu código esteja seguro para <em>release</em> após fazer alterações e de baixo custo de manutenção.</p>
+
+<p>Neste tutorial, mostramos como escrever e executar testes para seus <em>models</em>, <em>forms</em> e <em>views</em>. Mais importante ainda, fornecemos um breve resumo do que você deve testar, que geralmente é a coisa mais difícil de resolver quando você está iniciando. Há muito mais para conhecer, mas mesmo com o que você já aprendeu, poderá criar testes unitários eficazes para seus websites.</p>
+
+<p>O próximo e último tutorial mostra como você pode implantar seu maravilhoso (e totalmente testado!) website Django.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/testing/overview/">Escrevendo e executando testes</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial05/">Escrevendo seu primeiro app Django, parte 5 &gt; Introduzindo testes automatizados</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/">Refererências de ferramentas de teste</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/testing/advanced/">Tópicos avançados de testes</a> (Django docs)</li>
+ <li><a href="http://toastdriven.com/blog/2011/apr/10/guide-to-testing-in-django/">Um Guia para testes no Django</a> (Toast Driven Blog, 2011)</li>
+ <li><a href="http://test-driven-django-development.readthedocs.io/en/latest/index.html">Workshop: Desenvolvimento web Orientado a Testes com Django</a> (San Diego Python, 2014)</li>
+ <li><a href="https://realpython.com/blog/python/testing-in-django-part-1-best-practices-and-examples/">Testando no Django (Parte 1) - Melhores práticas e Exemplos</a> (RealPython, 2013)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Forms", "Learn/Server-side/Django/Deployment", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Usando models</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Authentication">Tutorial Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/tutorial_website_biblioteca_local/index.html b/files/pt-br/learn/server-side/django/tutorial_website_biblioteca_local/index.html
new file mode 100644
index 0000000000..da69f5c9de
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/tutorial_website_biblioteca_local/index.html
@@ -0,0 +1,98 @@
+---
+title: 'Tutorial Django: Website da Biblioteca Local'
+slug: Learn/Server-side/Django/Tutorial_website_biblioteca_local
+tags:
+ - Artigo
+ - Guía
+ - Iniciante
+ - Tutorial
+ - django
+translation_of: Learn/Server-side/Django/Tutorial_local_library_website
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">O primeiro artigo da nossa série de tutoriais práticos explica o que você irá aprender, e fornece uma visão do site de exemplo "biblioteca local" que estaremos trabalhando e evoluindo em artigos seguintes.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Ler a <a href="/pt-BR/docs/Learn/Server-side/Django/Introduction">introdução ao Django</a>. Para os próximos artigos você também necessitará ter montando o <a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">ambiente de desenvolvimento</a> para o Django.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Introduzir o exemplo da aplicação usado neste tutorial, e permitir que os leitores entendam quais tópicos serão abordados.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_geral">Visão geral</h2>
+
+<p>Bem vindo ao tutorial Django "Biblioteca Local" do MDN, no qual desenvolveremos um website que pode ser usado para gerenciar um catálogo para uma biblioteca local.</p>
+
+<p>Nessa série de artigos você irá:</p>
+
+<ul>
+ <li>Usar as ferramentas do Django para criar a estrutura de um website e aplicação.</li>
+ <li>Começar e parar o servidor de desenvolvimento.</li>
+ <li>Criar models para representar os dados da aplicação.</li>
+ <li>Usar o <em>admin</em> do Django para popular os dados do seu site.</li>
+ <li>Criar <em>views </em>para recuperar dados específicos em resposta a diferentes requisições, e <em>templates</em> para renderizar os dados como HTML para serem exibidos no navegador.</li>
+ <li>Criar <em>mappers</em> para associar diferentes padrões de URL com as<em>views</em> específicas.</li>
+ <li>Adicionar autorização de usuário e sessões para controlar o comportamento e acesso do site.</li>
+ <li>Trabalhar com formulários.</li>
+ <li>Criar teste de código para a sua aplicação.</li>
+ <li>Usar a segurança do Django de forma eficaz.</li>
+ <li>Implantar sua aplicação para produção. </li>
+</ul>
+
+<p>Você já aprendeu alguns desses tópicos e passou brevemente por outros. Até o final dessa série de tutoriais você deve saber o suficiente para desenvolver uma aplicação simples em Django sozinho.</p>
+
+<h2 id="Website_da_Biblioteca_Local_-_LocalLibrary">Website da Biblioteca Local - LocalLibrary</h2>
+
+<p><em>LocalLibrary</em> é o nome do site que vamos criar e evoluir ao longo dessa série de tutoriais. Como seria de esperar, a proposta do site é fornecer um catálogo online para uma pequena biblioteca local, onde os usuários podem procurar por livros disponíveis e gerenciar suas contas.</p>
+
+<p>Esse exemplo foi cuidadosamente escolhido porque escalar para mostrar quanto detalhe precisamos, muito ou pouco, e pode ser usado para mostrar quase qualquer recurso do Django. Mais importante ainda, nos permite fornecer um caminho <em>guiado</em> através da funcionalidade mais importante do estrutura web do Django:</p>
+
+<ul>
+ <li>Nos primeiros tutoriais, vamos definir uma biblioteca simples de <em>navegação exclusiva</em> que os membros podem usar para procurar quais livros estão disponíveis. Isso nos permite explorar operações simples que são comuns para quase todos os sites: leitura e exibição de conteúdo de um banco de dados</li>
+ <li>Conforme formos progredindo, o exemplo da biblioteca irá (naturalmente) se estender para demonstrar recursos mais avançados do Django. Nós podemos expandir a biblioteca, por exemplo, para permitir que usuários reservem livros, e usar isto para demonstrar como usar formulários e suporte a autenticação de usuários.</li>
+</ul>
+
+<p>Embora este seja um exemplo extenso, ele é chamado Biblioteca<strong> Local</strong> por uma razão - nós esperamos mostrar o mínimo de informação necessária para ajudar a desenvolver e executar uma aplicação com o Django rapidamente. Como resultado nós armazenaremos informações sobre livros, seus exemplares, autores e outras informações chave. Contudo, nós não armazenaremos informações sobre outros itens que uma biblioteca pode utilizar, ou fornecer a infraestrutura necessária para dar suporte a sites multi-biblioteca ou outros recursos do tipo "grande biblioteca".</p>
+
+<h2 id="Onde_posso_obter_o_código_fonte">Onde posso obter o código fonte?</h2>
+
+<p>Na medida em que você avança com o tutorial, nós forneceremos os fragmentos de código apropriados para que você possa copiá-los e colá-los em cada ponto. Também existirão outros códigos que você estenderá por conta própria (com alguma orientação).</p>
+
+<p>Se você travar, a versão completa do website pode ser encontrada<a href="https://github.com/mdn/django-locallibrary-tutorial"> aqui no Github</a>.</p>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Agora que você sabe um pouco mais sobre o website <em>LocalLIbrary</em> e o que você irá aprender, é hora de começar a criar um <a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">escopo do projeto</a>.</p>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}</p>
+
+
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Usando models</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Authentication">Tutorial Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/pt-br/learn/server-side/django/web_application_security/index.html b/files/pt-br/learn/server-side/django/web_application_security/index.html
new file mode 100644
index 0000000000..777a24a7cc
--- /dev/null
+++ b/files/pt-br/learn/server-side/django/web_application_security/index.html
@@ -0,0 +1,187 @@
+---
+title: Segurança de aplicações web Django
+slug: Learn/Server-side/Django/web_application_security
+tags:
+ - Aprender
+ - Artigo
+ - Codificação
+ - Iniciante
+ - Programação server-side
+ - Python
+ - Segurança
+ - Segurança web
+ - django
+ - lado servidor (server-side)
+translation_of: Learn/Server-side/Django/web_application_security
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Deployment", "Learn/Server-side/Django/django_assessment_blog", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Proteger dados do usuário é uma parte essencial de qualquer projeto de website. Anteriormente, explicamos algumas das ameaças de segurança mais comuns no artigo <a href="https://developer.mozilla.org/en-US/docs/Web/Security">Web security</a> — esse artigo fornece uma demonstração prática de como as proteções internas de Django lidam com essas ameaças.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Ler o tópico "<a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a>" de Programação Server-side. Conclua os tópicos do tutorial Django tutorial até (e incluindo) pelos menos <a href="/en-US/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>Para entender as principais coisas que você precisa fazer (ou não fazer) para proteger seu aplicatico web Django.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Visão_geral">Visão geral</h2>
+
+<p>O tópico <a href="https://developer.mozilla.org/en-US/docs/Web/Security">Website security</a> fornece uma visão geral do que  a segurança de website siginifica para o projeto server-side e algumas das ameaças mais comuns contra as quais você deve se proteger. Uma das mensagens chave nesse artigo é que quase todos os ataques são bem sucedidos quando a aplicação web confia nos dados do navegador.</p>
+
+<div class="warning">
+<p><strong>Importante:</strong> A lição mais importante que você pode aprender sobre segurança de website é <strong>nunca confiar nos dados do navegador</strong>. Isso inclui dados de requisição GET em parâmetros de URL, dados <code>POST</code>, cabeçalhos HTTP e cookies, arquivos enviados por usuários, etc. Sempre verifique e "desinfete" todos os dados recebidos. Sempre assuma o pior.</p>
+</div>
+
+<p>A boa notícia para usuários Django é que muitas das ameaças mais comuns são tratadas pelo framework! O artigo <a href="https://docs.djangoproject.com/en/2.0/topics/security/">Segurança no Django</a> (Django docs) explica os recursos de segurança e como proteger um website desenvolvido pelo Django.</p>
+
+<h2 id="Ameaçasproteções_comuns">Ameaças/proteções comuns</h2>
+
+<p>Em vez de  duplicar a documentação do Django aqui, neste artigo demonstraremos apenas alguns dos recursos de segurança no contexto do nosso tutorial Django da <a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>.</p>
+
+<h3 id="Cross_site_scripting_XSS">Cross site scripting (XSS)</h3>
+
+<p>XSS é um termo utilizado para descrever uma classe de ataques que permitem um invasor injetar scripts no lado cliente, através do website, no navegador de outros usuários. Issi geralmente é conseguido armazenando scripts maliciosos no banco de dados onde eles podem ser recuperado e exibidos para outros usuários, ou fazendo com que usuários cliquem em um link que fará com que o JavaScript do invasor seja executado pelo navegador do usuário.</p>
+
+<p>O sistema de <em>templates</em> do Django protege você da maioria dos ataques XSS <a href="https://docs.djangoproject.com/en/2.0/ref/templates/language/#automatic-html-escaping">escapando de caracteres específicos</a> que são "perigosos" em HTML. Podemos demonstrar isso tentando injetar algum JavaScript em nosso website LocalLibrary  usando o <em>form</em> Create-author que configuramos em <a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Parte 9: Trabalhando com formulários</a>.</p>
+
+<ol>
+ <li>Inicie o website usando o servidor de desenvolvimento (<code>python3 manage.py runserver</code>).</li>
+ <li>Abra o site em seu navegador local e faça login em sua conta de superusuário.</li>
+ <li>Navegue até a página de criação do autor (que deve estar na URL: <code><a href="http://127.0.0.1:8000/catalog/author/create/">http://127.0.0.1:8000/catalog/author/create/</a></code>).</li>
+ <li>Digite os nomes e os detalhes de data para um novo usuário, e então acrescente o seguinte texto no campo Last Name :<br>
+ <code>&lt;script&gt;alert('Test alert');&lt;/script&gt;</code>.<br>
+ <img alt="Author Form XSS test" src="https://mdn.mozillademos.org/files/14305/author_create_form_alert_xss.png" style="border-style: solid; border-width: 1px; height: 245px; width: 594px;">
+ <div class="note">
+ <p><strong>Nota:</strong> Este é um script inofensivo que, se executado, exibirá uma caixa de alerta em seu navegador. Se o alerta é exibido quando você submeter o registro então o site está vulnerável a ameaças XSS.</p>
+ </div>
+ </li>
+ <li>Pressione <strong>Submit</strong> para salvar o registro.</li>
+ <li>Quando você salvar o autor, ele será exibido como mostrado abaixo. Por causa das proteções XSS o <code>alert()</code> não deve ser executado. Em vez disso o script é exibido como texto simples.<img alt="Author detail view XSS test" src="https://mdn.mozillademos.org/files/14307/author_detail_alert_xss.png" style="border-style: solid; border-width: 1px; height: 248px; width: 986px;"></li>
+</ol>
+
+<p>Se você visualizar o código fonte da página HTML, poderá ver que os carcteres perigosos para as tags de script foram trasnformadoes em seus equivalentes de código de escape inofensivos (ex. <code>&gt;</code> agora é <code>&amp;gt;</code>)</p>
+
+<pre class="brush: html notranslate">&lt;h1&gt;Author: Boon&amp;lt;script&amp;gt;alert(&amp;#39;Test alert&amp;#39;);&amp;lt;/script&amp;gt;, David (Boonie) &lt;/h1&gt;
+</pre>
+
+<p>Usar templates Django protege você contra a maioria dos ataques de XSS. No entanto, é possível desativar esta proteção, e a proteção não é automaticamente aplicada a todas as tags que normalmente não seriam preenchidas pela entrada do usuário (por exemplo, o <code>help_text</code> em um campo de formulário normalmente não é preechido pelo usuário, então Django não escapa esses valores).</p>
+
+<p>Também é possível que os ataques XSS se originem de outra fonte de dados não confiável, como cookies, webservices ou upload de arquivos (sempre que os dados não forem suficientemente limpos antes de serem incluídos em uma página). Se estiver exibindo dados dessas fontes, então pode ser necessário adicionar seu próprio código de limpeza.</p>
+
+<h3 id="Proteção_contra_Cross_site_request_forgery_CSRF">Proteção contra Cross site request forgery (CSRF) </h3>
+
+<p>Ataques CSRF permitem que um usuário malicioso execute ações usando as credenciais de outro usuário sem o conhecimento ou consentimento desse usuário. Por exemplo, considere o caso em que temos um hacker que quer criar autores adicionais para nossa LocalLibrary.</p>
+
+<div class="note">
+<p><strong>Nota:</strong> Obviamente nosso hacker não está nisso por dinheiro! Um hacker mais ambicioso poderia usar a mesma abordagem em outros sites para realizar tarefas muito mais prejudiciais (ex. transferir dinheiro para suas prórpias contas, etc.)</p>
+</div>
+
+<p>Para fazer isso, eles podem criar um arquivo HTML como o abaixo, que contém um form de criação de autor (como o que usamos na seção anterior) que é enviado assim que o arquivo é carregado. Eles então enviariam o arquivo para todos os bibliotecários e sugeririam que eles abrissem o arquivo (ele contém algumas informações inofensivas, honestamente!). Se o arquivo for aberto por qualquer bibliotecário logado, o formulário será enviado com suas credenciais e um novo autor será criado.</p>
+
+<pre class="brush: html notranslate">&lt;html&gt;
+&lt;body onload='document.EvilForm.submit()'&gt;
+
+&lt;form action="http://127.0.0.1:8000/catalog/author/create/" method="post" name='EvilForm'&gt;
+ &lt;table&gt;
+ &lt;tr&gt;&lt;th&gt;&lt;label for="id_first_name"&gt;First name:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input id="id_first_name" maxlength="100" name="first_name" type="text" value="Mad" required /&gt;&lt;/td&gt;&lt;/tr&gt;
+ &lt;tr&gt;&lt;th&gt;&lt;label for="id_last_name"&gt;Last name:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input id="id_last_name" maxlength="100" name="last_name" type="text" value="Man" required /&gt;&lt;/td&gt;&lt;/tr&gt;
+ &lt;tr&gt;&lt;th&gt;&lt;label for="id_date_of_birth"&gt;Date of birth:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input id="id_date_of_birth" name="date_of_birth" type="text" /&gt;&lt;/td&gt;&lt;/tr&gt;
+ &lt;tr&gt;&lt;th&gt;&lt;label for="id_date_of_death"&gt;Died:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input id="id_date_of_death" name="date_of_death" type="text" value="12/10/2016" /&gt;&lt;/td&gt;&lt;/tr&gt;
+ &lt;/table&gt;
+ &lt;input type="submit" value="Submit" /&gt;
+&lt;/form&gt;
+
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>Execute o servidor web de desenvolvimento e faça login com a conta de superusuário. Copie o texto acima em um arquivo e abra-o no navegado. Você deve obter um erro de CSRF, porque Django tem protteção contra esse tipo de coisa!</p>
+
+<p>A forma como a proteção é habilitada é incluindo a tag de template <code>{% csrf_token %}</code> em sua definição de formulário. Esse token é então renderizado em seu HTML como mostrado abaixo com um valor que é específico para o usuário no navegador atual.</p>
+
+<pre class="brush: html notranslate">&lt;input type='hidden' name='csrfmiddlewaretoken' value='0QRWHnYVg776y2l66mcvZqp8alrv4lb8S8lZ4ZJUWGZFA5VHrVfL2mpH29YZ39PW' /&gt;
+</pre>
+
+<p>Django gera uma chave específica de usuário/navegador e irá rejeitar formulários que não contenham o campo, ou que contenham um valor de campo incorreto para o usuário/navegador.</p>
+
+<p>Para usar esse tipo de ataque o hacker agora precisa descobrir e incluir a chave CSRF para o usuário alvo específico. Eles também não podem usar a abordagem "scattergun" de enviar um arquivo malicioso para todos bibliotecários e esperar que um deles abra, já que a chave CSRF é específica do navegador.</p>
+
+<p>A proteção CSRF do Django é ativada por padrão. Você deve sempre usar a tag de template <code>{% csrf_token %}</code> em seus formulários e utilizar <code>POST</code> para requisições que podem alterar ou adicionar dados ao banco de dados.</p>
+
+<h3 id="Outras_proteções">Outras proteções</h3>
+
+<p>Django also provides other forms of protection (most of which would be hard or not particularly useful to demonstrate):</p>
+
+<dl>
+ <dt>Proteção contra Injeção de SQL</dt>
+ <dd>As vulnerabilidades de injeção de SQL (SQL injection) permitem usuários mal-intencionados executarem código SQL arbitrário em um banco de dados, permitindo que dados sejam acessados, modificados ou apagados independentemente das permissões do usuário. Em quase todos os casos você acessará o banco de dados usando querysets/models do Django, de mdo que o SQL resultante será devidamente escapado pelo driver de banco de dados subjacente. Se você precisa escrever consultas brutas ou SQL customizado precisará pensar explicitamente sobre como previnir injeção de SQL.</dd>
+ <dt>Proteção contra Clickjacking </dt>
+ <dd>Nesse ataque, um usuário malicioso sequestra clicks destinados a um site de visível no nível superior e os encaminha para uma página oculta abaixo. Essa técnica pode ser usada, por exemplo, para exibir um site de banco legítimo, mas capturar as credenciais de login em um <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe" title="The HTML Inline Frame Element (&lt;iframe>) represents a nested browsing context, effectively embedding another HTML page into the current page. In HTML 4.01, a document may contain a head and a body or a head and a frameset, but not both a body and a frameset. However, an &lt;iframe> can be used within a normal document body. Each browsing context has its own session history and active document. The browsing context that contains the embedded content is called the parent browsing context. The top-level browsing context (which has no parent) is typically the browser window."><code>&lt;iframe&gt;</code></a> invisível, controlado pelo atacante. O Django possui <a href="https://docs.djangoproject.com/en/2.0/ref/clickjacking/#clickjacking-prevention">proteção contra clickjacking</a> na forma do <a href="https://docs.djangoproject.com/en/2.0/ref/middleware/#django.middleware.clickjacking.XFrameOptionsMiddleware" title="django.middleware.clickjacking.XFrameOptionsMiddleware"><code>X-Frame-Options middleware</code></a> que, em um navegador de suporte, pode impedir que um site seja renderizado dentro de um frame.</dd>
+ <dt>Aplicação de SSL/HTTPS</dt>
+ <dd>SSL/HTTPS pode ser habilitado no servidor web para criptografar todo o tráfego entre o site e o navegador, incluindo credenciais de autenticação que seriam enviadas em texto simples (habilitar HTTPS é altamente recomendado). Se HTTPS estiver habilitado o Django fornece uma série de outras proteções que você pode utilizar:</dd>
+</dl>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER"><code>SECURE_PROXY_SSL_HEADER</code></a> pode ser utilizado para verificar se o conteúdo é seguro, mesmo se for recebido de um proxy não HTTP.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SECURE_SSL_REDIRECT"><code>SECURE_SSL_REDIRECT</code></a> é usado para redirecionar todas as requisições HTTP para HTTPS.</li>
+ <li>Usar <a href="https://docs.djangoproject.com/en/2.0/ref/middleware/#http-strict-transport-security">HTTP Strict Transport Security</a> (HSTS). Este é um cabeçalho HTTP que informa ao navegador que todas as conexões futuras com um determinado site devem sempre utilizar HTTPS. Combinada com o redirecionamento de requisições HTTP para HTTPS, essa configuração garante que HTTPS é sempre usado depois que uma conexão bem-sucedida ocorrer. HSTS pode ser configurado com <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SECURE_HSTS_SECONDS"><code>SECURE_HSTS_SECONDS</code></a> e <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SECURE_HSTS_INCLUDE_SUBDOMAINS"><code>SECURE_HSTS_INCLUDE_SUBDOMAINS</code></a> ou no servidor web.</li>
+ <li>Usar cookies "seguros" definindo <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SESSION_COOKIE_SECURE"><code>SESSION_COOKIE_SECURE</code></a> e <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-CSRF_COOKIE_SECURE"><code>CSRF_COOKIE_SECURE</code></a> como <code>True</code>. Isso garantirá que os cookies sejam enviados apenas por HTTPS.</li>
+</ul>
+
+<dl>
+ <dt>Validação de cabeçalho de host</dt>
+ <dd>Usar <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-ALLOWED_HOSTS"><code>ALLOWED_HOSTS</code></a> para aceitar apenas requisições de hosts confiáveis.</dd>
+</dl>
+
+<p>Existem muitas outras proteções, e ressalvas para o uso dos mecanismos acima. Embora esperamos que isso tenha dado a você uma visão geral do que o Django oferece, você ainda deve ler a documentação de segurança de Django.</p>
+
+<ul>
+</ul>
+
+<h2 id="Resumo">Resumo</h2>
+
+<p>Django tem proteções eficazes contra uma série de ameaças comuns, incluindo ataques XSS e CSRF. Neste artigo demonstramos como essas ameaças específicas são tratadas pelo Django em nosso website <em>LocalLibrary</em>. Também fornecemos uma breve visão geral de algumas das outras proteções.</p>
+
+<p>Esta foi uma incursão muito breve em segurança web. Nós recomendamos fortemente que você leia <a href="https://docs.djangoproject.com/en/2.0/topics/security/">Segurança no Django</a> para obter um entendimento mais profundo.</p>
+
+<p>A próxima e última etapa neste módulo sobre Django é concluir a <a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">tarefa de avaliação</a>.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.0/topics/security/">Segurança no Django</a> (Django docs)</li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/Security">Segurança de website no lado do servidor</a> (MDN)</li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/Security">Segurança web</a> (MDN)</li>
+ <li><a href="/en-US/docs/Web/Security/Securing_your_site">Protegendo seu site</a> (MDN)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Deployment", "Learn/Server-side/Django/django_assessment_blog", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Neste_módulo">Neste módulo</h2>
+
+<ul>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Introduction">Introdução ao Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/development_environment">Configurando um ambiente de desenvolvimento Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django: Website de uma Biblioteca Local</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/skeleton_website">Tutorial Django Parte 2: Criando a base do website</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Models">Tutorial Django Parte 3: Usando models</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Admin_site">Tutorial Django Parte 4: Django admin site</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Home_page">Tutorial Django Parte 5: Criando nossa página principal</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Generic_views">Tutorial Django Parte 6: Lista genérica e detail views</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Sessions">Tutorial Django Parte 7: Framework de Sessões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Authentication">Tutorial Django Parte 8: Autenticação de Usuário e permissões</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Forms">Tutorial Django Parte 9: Trabalhando com formulários</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Testing">Tutorial Django Parte 10: Testando uma aplicação web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/Deployment">Tutorial Django Parte 11: Implantando Django em produção</a></li>
+ <li><a rel="nofollow" title="A página ainda não foi criada.">Segurança de aplicações web Django</a></li>
+ <li><a href="/pt-BR/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>