Tutorial Django Parte 7: Sessões - Aprendendo desenvolvimento web

Tutorial Django Parte 7: Sessões
================================

* Anterior
* Menu: Django
* Próxima  (en-US)

Esse tutorial estende nosso site LocalLibrary, 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.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Completar todos os tópicos anteriores do tutorial, incluindo
 Django Tutorial Part 6: Generic list and detail views |
| Objetivo: | Entender como as sessões são usadas. |

Visão Geral
-----------

O site LocalLibrary 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.

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 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).

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.

O que são sessões?
------------------

Toda a comunicação entre os navegadores web e os servidores é feita via protocolo HTTP, qual é *stateless* (sem estados). O fato do protocolo ser stateless significa que as mensagens 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. 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.

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.

O Django usa um cookie contendo um *identificador* 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 perigosos). 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".

Habilitando as Sessões
----------------------

As sessões foram ativadas automaticamente quando criamos o esqueleto do site (no tutorial 2).

A configuração e feita nas seções `INSTALLED_APPS` e `MIDDLEWARE` do arquivo (**locallibrary/locallibrary/settings.py**), exibidas a seguir:

```python
INSTALLED_APPS = [
    ...
    'django.contrib.sessions',
    ....

MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    ....
```

Usando Sessões
--------------

Você pode acessar o atributo `session` na view a partir do parâmetro `request` (um `HttpRequest` passado como primeiro argumento na view). Esse atributo de sessão representa a conexão atual específica com um usuário (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).

O atributo `session` é 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, iterar (loop) em torno dos dados, etc. Na maior parte do tempo, você usará apenas a API padrão "dictionary" para obter e setar valores.

O fragmento de código abaixo mostra como você pode obter, setar e deletar qualquer dado com com a chave "`my_car`", associada com a sessão atual (navegador).

**Nota:** 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 `my_car` estão associadas apenas com o navegador que enviou a requisição atual.

```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']
```

A API também oferece um número de outros métodos que são muito usados para gerenciar os cookies da sessão associada. Por exemplo, há métodos 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 How to use sessions (documentação do Django).

Salvando os dados da sessão
---------------------------

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 é *modificada* (atribuída) ou *deletada*. 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:

```python
# Isso é detectado como uma atualização na session, então os dados de session são salvos.
request.session['my\_car'] = 'mini'
```

Se você está atualizando algumas informações *dentro* 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 "`wheels`" dentro dos dados do seu "`my_car`", como mostrado abaixo). Nesse caso você precisará marcar explicitamente a sessão como tendo sido modificada.

```python
# Objeto session não modificado diretamente, apenas o dado de dentro da session. Mudanças na session não salvas!
request.session['my\_car']['wheels'] = 'alloy'

# Marcar a session como modificada para que force a atualização dos dados/cookie para que sejam salvos.
request.session.modified = True
```

**Nota:** Você pode mudar o comportamento do site para atualizar a base de dados/enviar cookie em qualquer requisição adicionando `SESSION_SAVE_EVERY_REQUEST = True` nas configurações (**locallibrary/locallibrary/settings.py**) do seu projeto.

Exemplo simples - obtendo a contagem de visitas
-----------------------------------------------

Como um exemplo simples do mundo real, atualizaremos nossa biblioteca para informar ao usuário atual quantas vezes ele visitou o site *LocalLibrary*.

Abra **/locallibrary/catalog/views.py**, e faça as alterações mostradas em negrito abaixo.

```python
def index(request):
    ...

    num_authors = Author.objects.count()  # The 'all()' is implied by default.

    # 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

    context = {
        'num\_books': num_books,
        'num\_instances': num_instances,
        'num\_instances\_available': num_instances_available,
        'num\_authors': num_authors,
        'num\_visits': num_visits,
    }

    # Render the HTML template index.html with the data in the context variable.
    return render(request, 'index.html', context=context)
```

Aqui primeiro obtemos o valor da *session key* `'num_visits'`, setando o valor para 0 se não tiver sido definido anteriormente. 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 `num_visits` é então passada para o *template* na nossa variável *context*.

**Nota:** Também podemos testar se os cookies são suportados no navegador (veja Como usar sessões para exemplos) ou projetar nossa UI (interface do usuário) para que não se importe se os *cookies* são ou não suportados.

Adicione a linha vista na parte inferior do bloco a seguir ao seu *template* HTML principal (**/locallibrary/catalog/templates/index.html**) na parte inferior da sessão *"Dynamic content"*, para exibir a variável *context*:

```django
<h2>Dynamic content</h2>

<p>The library has the following record counts:</p>
<ul>
  <li><strong>Books:</strong> {{ num\_books }}</li>
  <li><strong>Copies:</strong> {{ num\_instances }}</li>
  <li><strong>Copies available:</strong> {{ num\_instances\_available }}</li>
  <li><strong>Authors:</strong> {{ num\_authors }}</li>
</ul>

<p>
  You have visited this page {{ num\_visits }}{% if num\_visits == 1 %} time{%
 else %} times{% endif %}.
</p>
```

Salve suas alterações e reinicie o servidor de teste. Sempre que você atualiza a página, o número deve ser atualizado.

Resumo
------

Agora você sabe como é fácil utilizar sessões para melhorar sua interação com usuários anônimos.

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.

Veja também
-----------

* Como usar sessões (Django docs)
* Anterior
* Menu: Django
* Próxima


Tutorial Django: Website da Biblioteca Local - Aprendendo desenvolvimento web

Tutorial Django: Website da Biblioteca Local
============================================

* Anterior
* Menu: Django
* Próxima

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.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Ler a
 introdução ao Django. Para os próximos artigos você também necessitará ter montando o
 ambiente de desenvolvimento
 para o Django.
  |
| Objetivo: |
 Introduzir o exemplo da aplicação usado neste tutorial, e permitir que
 os leitores entendam quais tópicos serão abordados.
  |

Visão geral
-----------

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.

Nessa série de artigos você irá:

* Usar as ferramentas do Django para criar a estrutura de um website e aplicação.
* Começar e parar o servidor de desenvolvimento.
* Criar models para representar os dados da aplicação.
* Usar o *admin* do Django para popular os dados do seu site.
* Criar *views* para recuperar dados específicos em resposta a diferentes requisições, e *templates* para renderizar os dados como HTML para serem exibidos no navegador.
* Criar *mappers* para associar diferentes padrões de URL com as*views* específicas.
* Adicionar autorização de usuário e sessões para controlar o comportamento e acesso do site.
* Trabalhar com formulários.
* Criar teste de código para a sua aplicação.
* Usar a segurança do Django de forma eficaz.
* Implantar sua aplicação para produção.

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.

Website da Biblioteca Local - LocalLibrary
------------------------------------------

*LocalLibrary* é 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.

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 *guiado* através da funcionalidade mais importante do estrutura web do Django:

* Nos primeiros tutoriais, vamos definir uma biblioteca simples de *navegação exclusiva* 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
* 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.

Embora este seja um exemplo extenso, ele é chamado Biblioteca **Local** 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".

Onde posso obter o código fonte?
--------------------------------

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).

Se você travar, a versão completa do website pode ser encontrada aqui no Github.

Resumo
------

Agora que você sabe um pouco mais sobre o website *LocalLIbrary* e o que você irá aprender, é hora de começar a criar um escopo do projeto.

* Anterior
* Menu: Django
* Próxima


Tutorial Django Parte 8: Autenticação de usuário e permissões - Aprendendo desenvolvimento web

Tutorial Django Parte 8: Autenticação de usuário e permissões
=============================================================

* Anterior
* Menu: Django
* Próxima

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 LocalLibrary website, adicionando páginas de login e logout e páginas específicas do usuário e da equipe para visualizar os livros emprestados.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Conclua todos os tópicos do tutorial anterior, incluindo
 Django Tutorial Part 7: Sessions framework.
  |
| Objetivo: |
 Para entender como configurar e usar a autenticação e permissões de
 usuário.
  |

Visão global
------------

O Django fornece um sistema de autenticação e autorização ("permissão"), construído sobre a estrutura da sessão discutida no tutorial anterior, 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 `Users` e `Groups` (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.

**Nota:** 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).

Neste tutorial, mostraremos como habilitar a autenticação do usuário no diretório LocalLibrary 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.

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.

Também mostraremos como criar permissões e verificar o status e as permissões de login nas visualizações e nos modelos.

Ativando a autenticação
-----------------------

A autenticação foi ativada automaticamente quando criamos o esqueleto do site (no tutorial 2), para que você não precise fazer mais nada neste momento.

**Nota:** A configuração necessária foi feita para nós quando criamos o aplicativo usando o comando `django-admin startproject`. As tabelas de banco de dados para usuários e permissões de modelo foram criadas quando chamamos pela primeira vez `python manage.py migrate`.

A configuração está definida nas seções `INSTALLED_APPS` e `MIDDLEWARE` no settings.py (**locallibrary/locallibrary/settings.py**), como mostrado abaixo:

```python
INSTALLED_APPS = [
    ...
    'django.contrib.auth',  #Core authentication framework and its default models.
    'django.contrib.contenttypes',  #Django content type system (allows permissions to be associated with models).
    ....

MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',  #Manages sessions across requests
    ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',  #Associates users with requests using sessions.
    ....
```

Criando usuários e grupos
-------------------------

Você já criou seu primeiro usuário quando olhamos para o site Django admin no tutorial 4 (este era um superusuário, criado com o comando `python manage.py createsuperuser)`. 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.

**Nota:** 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).

```python
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()
```

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.

Inicie o servidor de desenvolvimento e navegue até o site de administração em seu navegador da web local (`http://127.0.0.1:8000/admin/`). 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 **Autenticação e Autorização**, você pode clicar nos links **Usuários** ou **Grupos** para ver seus registros existentes.

![Admin site - add groups or users](/pt-BR/docs/Learn/Server-side/Django/Authentication/admin_authentication_add.png)

Primeiro vamos criar um novo grupo para os membros da nossa biblioteca.

1. Clique no botão **Adicionar** (ao lado de Grupo) para criar um novo grupo; digite o **Nome** "Library Members" para o grupo.
 ![Admin site - add group](/pt-BR/docs/Learn/Server-side/Django/Authentication/admin_authentication_add_group.png)
2. Não precisamos de permissões para o grupo, então pressione **SALVAR** (você será direcionado para uma lista de grupos).

Agora vamos criar um usuário:

1. Volte para a página inicial do site de administração
2. Clique no botão **Adicionar** ao lado de *Usuários* para abrir a caixa de diálogo *Adicionar usuário*.
 ![Admin site - add user pt1](/pt-BR/docs/Learn/Server-side/Django/Authentication/admin_authentication_add_user_prt1.png)
3. Digite um nome de **usuário** e uma **senha/confirmação de senha** adequados para o usuário de teste
4. Pressione **SALVAR** para criar o usuário.
 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 **nome de usuário** 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 **Ativo** 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).
 ![Admin site - add user pt2](/pt-BR/docs/Learn/Server-side/Django/Authentication/admin_authentication_add_user_prt2.png)
5. Na seção *Grupos*, selecione grupo de **Library Members** na lista de *Grupos disponíveis* e pressione a **seta para a direita** entre as caixas para movê-lo para a caixa *Grupos escolhidos*.
 ![Admin site - add user to group](/pt-BR/docs/Learn/Server-side/Django/Authentication/admin_authentication_user_add_group.png)
6. Não precisamos fazer mais nada aqui; basta selecionar **SALVAR** novamente, para ir para a lista de usuários.

É 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).

**Nota:** 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!

Configurando suas views de autenticação
---------------------------------------

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!

Nesta seção, mostramos como integrar o sistema padrão no site *LocalLibrary* e criar os modelos. Vamos colocá-los nos principais URLs do projeto.

**Nota:** 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.

>
> \*\*Nota:\*\*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!
>
>
>

### URLs do Projeto

Adicione o seguinte à parte inferior do arquivo urls.py do projeto (**locallibrary/locallibrary/urls.py**):

```python
#Add Django site authentication urls (for login, logout, password management)
urlpatterns += [
    path('accounts/', include('django.contrib.auth.urls')),
]
```

Navegue até URL `http://127.0.0.1:8000/accounts/` (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:

>
> \*\*Nota:\*\*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.
>
>
> python
> ```python
> 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/<uidb64>/<token>/ [name='password\_reset\_confirm']
> accounts/ reset/done/ [name='password\_reset\_complete']
>
> ```
>
>

Agora tente navegar para o URL de login (`http://127.0.0.1:8000/accounts/login/`). Isso falhará novamente, mas com um erro informando que estamos perdendo o modelo necessário (**registration/login.html**) no caminho de pesquisa do modelo. Você verá as seguintes linhas listadas na seção amarela na parte superior:

```python
Exception Type:    TemplateDoesNotExist
Exception Value:    registration/login.html
```

A próxima etapa é criar um diretório de registro no caminho de pesquisa e adicionar o arquivo **login.html**.

### Diretório de Templates

Os URLs (e implicitamente, visualizações) que acabamos de adicionar esperam encontrar seus modelos associados em um diretório **/registration/** em algum lugar no caminho de pesquisa de modelos.

Neste site, colocaremos nossas páginas HTML no diretório **templates/registration/**. Esse diretório deve estar no diretório raiz do projeto, ou seja, o mesmo diretório que a pasta **catalog** e **locallibrary**. Por favor, crie essas pastas agora.

**Nota:** Sua estrutura de pastas agora deve se parecer como abaixo:
 locallibrary (Django project folder)
 |\_catalog
 |\_locallibrary
 |\_templates **(new)**
 |\_registration

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 (**/locallibrary/locallibrary/settings.py**) e atualize o seção `TEMPLATES` linha `'DIRS'` como mostrado abaixo.

```python
TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP\_DIRS': True,
        ...
```

### Template de login

**Aviso:** **Importante**: 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!

Crie um novo arquivo HTML chamado **/locallibrary/templates/registration/login.html** e forneça o seguinte conteúdo:

```django
{% extends "base\_generic.html" %}

{% block content %}

  {% if form.errors %}
    <p>Your username and password didn't match. Please try again.</p>
  {% endif %}

  {% if next %}
    {% if user.is\_authenticated %}
      <p>Your account doesn't have access to this page. To proceed,
      please login with an account that has access.</p>
    {% else %}
      <p>Please login to see this page.</p>
    {% endif %}
  {% endif %}

  <form method="post" action="{% url 'login' %}">
    {% csrf\_token %}
    <table>
      <tr>
        <td>{{ form.username.label\_tag }}</td>
        <td>{{ form.username }}</td>
      </tr>
      <tr>
        <td>{{ form.password.label\_tag }}</td>
        <td>{{ form.password }}</td>
      </tr>
    </table>
    <input type="submit" value="login" />
    <input type="hidden" name="next" value="{{ next }}" />
  </form>

  {# Assumes you setup the password\_reset view in your URLconf #}
  <p><a href="{% url 'password\_reset' %}">Lost password?</a></p>

{% endblock %}
```

Este modelo compartilha algumas semelhanças com as que já vimos antes - estende nosso modelo base e substitui o bloco `content`. 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.

Navegue de volta para a página de login (`http://127.0.0.1:8000/accounts/login/`). Depois de salvar seu modelo, você verá algo assim:

![Library login page v1](/pt-BR/docs/Learn/Server-side/Django/Authentication/library_login.png)

Se você fizer login usando credenciais válidas, será redirecionado para outra página (por padrão, isso será `http://127.0.0.1:8000/accounts/profile/`). 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!

Abra as configurações do projeto (**/locallibrary/locallibrary/settings.py**) 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.

```python
# Redirect to home URL after login (Default redirects to /accounts/profile/)
LOGIN_REDIRECT_URL = '/'
```

### Template de logout

Se você navegar para o URL de logout (`http://127.0.0.1:8000/accounts/logout/`) você verá um comportamento estranho - seu usuário será desconectado com certeza, mas será direcionado para a pagina de logout do **Admin**. 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 `is_staff`).

Crie e abra /**locallibrary/templates/registration/logged\_out.html**. Copie o texto abaixo:

```django
{% extends "base\_generic.html" %}

{% block content %}
  <p>Logged out!</p>
  <a href="{% url 'login'%}">Click here to login again.</a>
{% endblock %}
```

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:

![Library logout page v1](/pt-BR/docs/Learn/Server-side/Django/Authentication/library_logout.png)

### Templates para reset de password

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.

Os seguintes modelos podem ser usados como ponto de partida.

#### Formulário para reset de password

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 **/locallibrary/templates/registration/password\_reset\_form.html** e forneça o seguinte conteúdo:

```django
{% extends "base\_generic.html" %}

{% block content %}
  <form action="" method="post">
  {% csrf\_token %}
  {% if form.email.errors %}
    {{ form.email.errors }}
  {% endif %}
      <p>{{ form.email }}</p>
    <input type="submit" class="btn btn-default btn-lg" value="Reset password">
  </form>
{% endblock %}
```

#### Password reset done

Este formulário é exibido após a coleta do seu endereço de email. Crie **/locallibrary/templates/registration/password\_reset\_done.html**, e forneça o seguinte conteúdo:

```django
{% extends "base\_generic.html" %}

{% block content %}
  <p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
{% endblock %}
```

#### Password reset email

Este modelo fornece o texto do email em HTML que contém o link de redefinição que enviaremos aos usuários. Crie **/locallibrary/templates/registration/password\_reset\_email.html** e forneça o seguinte conteúdo:

```django
Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password\_reset\_confirm' uidb64=uid token=token %}
```

#### Password reset confirm

É nesta página que você digita sua nova senha depois de clicar no link no e-mail de redefinição de senha. Crie **/locallibrary/templates/registration/password\_reset\_confirm.html** e forneça o seguinte conteúdo:

```django
{% extends "base\_generic.html" %}

{% block content %}
  {% if validlink %}
    <p>Please enter (and confirm) your new password.</p>
    <form action="" method="post">
      {% csrf\_token %}
      <table>
        <tr>
          <td>
            {{ form.new\_password1.errors }}
            <label for="id\_new\_password1">New password:</label>
          </td>
          <td>{{ form.new\_password1 }}</td>
        </tr>
        <tr>
          <td>
            {{ form.new\_password2.errors }}
            <label for="id\_new\_password2">Confirm password:</label>
          </td>
          <td>{{ form.new\_password2 }}</td>
        </tr>
        <tr>
          <td></td>
          <td><input type="submit" value="Change my password" /></td>
        </tr>
      </table>
    </form>
  {% else %}
    <h1>Password reset failed</h1>
    <p>
      The password reset link was invalid, possibly because it has already been
      used. Please request a new password reset.
    </p>
  {% endif %}
{% endblock %}
```

#### Password reset complete

Este é o último modelo de redefinição de senha, exibido para notificá-lo quando a redefinição de senha for bem-sucedida. Crie **/locallibrary/templates/registration/password\_reset\_complete.html** e forneça o seguinte conteúdo:

```django
{% extends "base\_generic.html" %}

{% block content %}
  <h1>The password has been changed!</h1>
  <p><a href="{% url 'login' %}">log in again?</a></p>
{% endblock %}
```

### Testando as novas páginas de autenticação

Agora que você adicionou a configuração da URL e criou todos esses modelos, as páginas de autenticação agora devem funcionar!

Você pode testar as novas páginas de autenticação tentando fazer login e sair da sua conta de superusuário usando estes URLs:

* `http://127.0.0.1:8000/accounts/login/`
* `http://127.0.0.1:8000/accounts/logout/`

Você poderá testar a funcionalidade de redefinição de senha no link na página de login. **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!**

**Nota:** 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).

```python
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
```

Para mais informações, veja Sending email (Django docs).

Testando contra usuários autenticados
-------------------------------------

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.

### Testando nos templates

Você pode obter informações sobre o usuário conectado no momento em modelos com a variável de template `{{ user }}` (isso é adicionado ao contexto do template por padrão quando você configura o projeto como fizemos em nosso esqueleto).

Normalmente você primeiro testará contra a variável de template `{{ user.is_authenticated }}` 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.

Abra o template base (**/locallibrary/catalog/templates/base\_generic.html**) e copie o texto a seguir no bloco `sidebar`, imediatamente antes da template tag `endblock`.

```django
  <ul class="sidebar-nav">
    ...

    {% if user.is\_authenticated %}
      <li>User: {{ user.get\_username }}</li>
      <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>
    {% else %}
      <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>
    {% endif %}
  </ul>
```

Como você pode ver, usamos template tags `if`-`else`-`endif` para exibir condicionalmente o texto com base em `{{ user.is_authenticated }}` ser verdadeiro. Se o usuário estiver autenticado, sabemos que temos um usuário válido, por isso chamamos `{{ user.get_username }}` para exibir o nome deles.

Criamos os URLs dos links de logon e logout usando a template tag `url` e os nomes das respectivas configurações de URL. Observe também como anexamos `?next={{request.path}}` 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 "`next`" para redirecionar o usuário de volta à página em que ele clicou pela primeira vez no link de logon/logout.

**Nota:** 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.

### Testando nas views

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 `login_required` à 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.(`settings.LOGIN_URL`), passando o caminho absoluto atual como o `next` no parametro da URL. Se o usuário conseguir fazer login, ele retornará a esta página, mas desta vez autenticado.

```python
from django.contrib.auth.decorators import login_required

@login\_required
def my\_view(request):
    ...
```

**Nota:** Você pode fazer o mesmo tipo de coisa manualmente testando em`request.user.is_authenticated`, mas o decorator é muito mais conveniente!

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 `LoginRequiredMixin`. Você precisa declarar esse mixin primeiro na lista de superclasses, antes da classe de visualização principal.

```python
from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    ...
```

Isso tem exatamente o mesmo comportamento de redirecionamento que o decorator `login_required`. Você também pode especificar um local alternativo para redirecionar o usuário se ele não estiver autenticado (`login_url`), e um nome de parâmetro de URL em vez de "`next`" para inserir o caminho absoluto atual (`redirect_field_name`).

```python
class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect\_to'
```

Para detalhes adicionais, consulte o Django docs here.

Exemplo - listando os livros do usuário atual
---------------------------------------------

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.

Infelizmente, ainda não temos como os usuários emprestarem livros! Portanto, antes que possamos criar a lista de livros, primeiro estenderemos o modelo `BookInstance` para suportar o conceito de empréstimo e usar o aplicativo Django Admin para emprestar vários livros ao nosso usuário de teste.

### Models

Primeiro, teremos que possibilitar que os usuários tenham um `BookInstance` emprestado (já temos um `status` e uma data `due_back`, mas ainda não temos nenhuma associação entre esse modelo e um usuário. Vamos criar um usando um campo `ForeignKey` (one-to-many). Também precisamos de um mecanismo fácil para testar se um livro emprestado está vencido.

Abra **catalog/models.py**, e importe o model `User` de `django.contrib.auth.models` (adicione isso logo abaixo da linha de importação anterior na parte superior do arquivo, para `User` estar disponível para o código subsequente que faz uso dele):

```python
from django.contrib.auth.models import User
```

Em seguida, adicione o campo `borrower` para o modelo `BookInstance`:

```python
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
```

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 property como mostrado abaixo será muito mais eficiente.

Adicione isso em algum lugar perto da parte superior do arquivo:

```python
from datetime import date
```

Agora adicione a seguinte definição de propriedade a classe `BookInstance`:

```python
@property
def is\_overdue(self):
    if self.due_back and date.today() > self.due_back:
        return True
    return False
```

**Nota:** Primeiro, verificamos se `due_back` está vazio antes de fazer uma comparação. Um campo `due_back` 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!

Agora que atualizamos nossos modelos, precisaremos fazer novas migrações no projeto e aplicá-las:

```bash
python3 manage.py makemigrations
python3 manage.py migrate
```

### Admin

Agora abra **catalog/admin.py**, e adicione o campo `borrower` para a classe `BookInstanceAdmin` em ambos os `list_display` e o `fieldsets` como mostrado abaixo. Isso tornará o campo visível na seção Admin, permitindo atribuir um `User` para um `BookInstance` quando necessário.

```python
@admin.register(BookInstance)
class BookInstanceAdmin(admin.ModelAdmin):
    list_display = ('book', 'status', 'borrower', 'due\_back', 'id')
    list_filter = ('status', 'due\_back')

    fieldsets = (
        (None, {
            'fields': ('book','imprint', 'id')
        }),
        ('Availability', {
            'fields': ('status', 'due\_back','borrower')
        }),
    )
```

### Emprestando alguns livros

Agora que é possível emprestar livros para um usuário específico, vá e empreste vários `BookInstance`. Defina o campo `borrowed` para o usuário de teste, faça o `status` "On loan", e defina datas de vencimento no futuro e no passado.

**Nota:** Não detalharemos o processo, pois você já sabe como usar o site Admin!

### Na view loan

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 `LoginRequiredMixin`, para que apenas um usuário conectado possa chamar essa visualização. Também optaremos por declarar um `template_name`, em vez de usar o padrão, pois podemos ter algumas listas diferentes de registros BookInstance, com diferentes visualizações e modelos.

Adicione o seguinte a **catalog/views.py**:

```python
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')
```

Para restringir nossa consulta apenas ao objeto `BookInstance` para o usuário atual, reimplementamos `get_queryset()` como mostrado abaixo. Observe que "o" is the stored code for "on loan" (emprestado) e nós pedimos pela data `due_back` para que os itens mais antigos sejam exibidos primeiro.

### URL conf para livros on loan (emprestado)

Agora abra **/catalog/urls.py** e adicione um `path()` apontando para a visualização acima (você pode copiar o texto abaixo no final do arquivo).

```python
urlpatterns += [
    path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
]
```

### Template para livros on loan (emprestado)

Agora, tudo o que precisamos fazer para esta página é adicionar um modelo. Primeiro, crie o arquivo de modelo **/catalog/templates/catalog/bookinstance\_list\_borrowed\_user.html** e forneça o seguinte conteúdo:

```python
{% extends "base\_generic.html" %}

{% block content %}
    <h1>Borrowed books</h1>

    {% if bookinstance_list %}
    <ul>

      {% for bookinst in bookinstance_list %}
      <li class="{% if bookinst.is\_overdue %}text-danger{% endif %}">
        <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }})
      </li>
      {% endfor %}
    </ul>

    {% else %}
      <p>There are no books borrowed.</p>
    {% endif %}
{% endblock %}
```

Este modelo é muito semelhante ao que criamos anteriormente para os objetos `Book` e `Author`. A única coisa "nova" aqui é que verificamos o método que adicionamos no modelo `(bookinst.is_overdue`) e use-o para alterar a cor dos itens em atraso.

Quando o servidor de desenvolvimento estiver em execução, agora você poderá visualizar a lista de um usuário conectado no seu navegador em `http://127.0.0.1:8000/catalog/mybooks/`. Experimente isso com o usuário conectado e desconectado (no segundo caso, você deve ser redirecionado para a página de login).

### Adicione a lista à barra lateral

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.

Abra o template base (**/locallibrary/catalog/templates/base\_generic.html**) e adicione a linha em negrito à barra lateral, como mostrado.

```python
 <ul class="sidebar-nav">
   {% if user.is_authenticated %}
   <li>User: {{ user.get_username }}</li>
   <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li>
   <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>
   {% else %}
   <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>
   {% endif %}
 </ul>
```

### Com o que se parece?

Quando qualquer usuário estiver conectado, ele verá o link *My Borrowed* 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!) .

![Library - borrowed books by user](/pt-BR/docs/Learn/Server-side/Django/Authentication/library_borrowed_by_user.png)

Permissões
----------

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.

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).

### Models

A definição de permissões é feita na seção "`class Meta`" do modelo, usando o campo `permissions`. 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:

```python
class BookInstance(models.Model):
    ...
    class Meta:
        ...
        permissions = (("can\_mark\_returned", "Set book as returned"),)
```

Poderíamos então atribuir a permissão a um grupo "Librarian" no site do administrador.

Abra **catalog/models.py**, e adicione a permissão como mostrado acima. Você ira precisar atualizar seus *migrations* (execute `python3 manage.py makemigrations` e `python3 manage.py migrate`) para atualizar o banco de dados apropriadamente.

### Templates

As permissões do usuário atual são armazenadas em uma variável de modelo chamada `{{ perms }}`. 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. `{{ perms.catalog.can_mark_returned }}` será `True` se o usuário tiver essa permissão, caso contrário, `False`. Normalmente testamos a permissão usando a template tag `{% if %}` como mostrado:

```python
{% if perms.catalog.can_mark_returned %}
    <!-- We can mark a BookInstance as returned. -->
    <!-- Perhaps add code to link to a "book return" view here. -->
{% endif %}
```

### Views

As permissões podem ser testadas na exibição de funções usando o decorator `permission_required` ou em uma view baseada em classe usando o `PermissionRequiredMixin`. 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.

Função view decorator:

```python
from django.contrib.auth.decorators import permission_required

@permission\_required('catalog.can\_mark\_returned')
@permission\_required('catalog.can\_edit')
def my\_view(request):
    ...
```

Um permission-required mixin para class-based views.

```python
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!
```

### Exemplo

Não atualizaremos a *LocalLibrary* aqui; talvez no próximo tutorial!

Desafie-se
----------

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 *todos* os livros que foram emprestados e que inclua o nome de cada mutuário.

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: `staff_member_required`, variável do template: `user.is_staff`) mas recomendamos que você use a permissão `can_mark_returned` e `PermissionRequiredMixin`, conforme descrito na seção anterior.

**Aviso:** **Importante**: 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.

Quando terminar, sua página será semelhante à captura de tela abaixo.

![All borrowed books, restricted to librarian](/pt-BR/docs/Learn/Server-side/Django/Authentication/library_borrowed_all.png)

Resumo
------

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.

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.

Veja também
-----------

* Autenticação de usuário no Django (Django docs)
* Usando o sistema (default) de Autenticação do Django (Django docs)
* Introdução a views baseadas em classe > Decorating class-based views (Django docs)
* Anterior
* Menu: Django
* Próxima


Tutorial Django Parte 4: Django admin site - Aprendendo desenvolvimento web

Tutorial Django Parte 4: Django admin site
==========================================

* Anterior
* Menu: Django
* Próxima

Agora que criamos modelos para o site da LocalLibrary, 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.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Primeiro complete:
 Tutorial Django Parte 3: Usando modelos.
  |
| Objetivo: |
 Para entender os benefícios e limitações do site de administração do
 Django, use-o para criar alguns registros para nossos modelos.
  |

Visão Geral
-----------

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.

Toda a configuração necessária para incluir o aplicativo admin em seu site foi feita automaticamente quando você criou o esqueleto do projeto (para obter informações sobre as dependências reais necessárias, consulte a documentação do Django aqui). 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.

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.

Registrando modelos
-------------------

Primeiro, abra o admin.py no aplicativo de catálogo (/locallibrary/catalog/admin.py). Atualmente parece com isso - note que ele já importa `django.contrib.admin`:

```python
from django.contrib import admin

# Register your models here.
```

Registre os modelos copiando o seguinte texto na parte inferior do arquivo. Este código simplesmente importa os modelos e, em seguida, chama `admin.site.register` para registrar cada um deles.

```python
from catalog.models import Author, Genre, Book, BookInstance

admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Genre)
admin.site.register(BookInstance)
```

**Nota:** Nota: Se você aceitou o desafio de criar um modelo para representar a linguagem natural de um livro (consulte o artigo do tutorial de modelos), importe-o e registre-o também!

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.

Criando um super usuário
------------------------

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 **manage.py**.

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.

```bash
python3 manage.py createsuperuser
```

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:

```bash
python3 manage.py runserver
```

Fazendo o login e usando o site
-------------------------------

Para fazer login no site, abra o URL /*admin* (e.g. http://127.0.0.1:8000/admin) 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 /*admin* depois de inserir seus detalhes).

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.

![Admin Site - Home page](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_home.png)

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 `help_text` (se houver) correspondem aos valores especificados no modelo.

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 **SALVAR, Salvar** **e adicionar** outro ou S**alvar e continuar editando** para salvar o registro.

![Admin Site - Book Add](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_book_add.png)

**Nota:** 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).

Quando terminar de adicionar livros, clique no link **Home** no marcador superior para ser levado de volta à página principal do administrador. Então clique no link **Books** 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 `__str__()` que especificamos no último artigo.

![Admin Site - List of book objects](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_book_list.png)

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 **ADD BOOK**.

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 **Delete**, **HISTORY** e **VIEW ON SITE** (este último botão aparece porque definimos o método `get_absolute_url()` em nosso modelo).

![Admin Site - Book Edit](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_book_modify.png)

Agora navegue de volta para o **Home** page (usando o link Home, a trilha de navegação) e, em seguida, **Author** e listas de **Genre** — você já deve ter criado a partir de quando adicionou os novos livros, mas fique à vontade para adicionar um pouco mais.

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 `Book` a partir de `BookInstance` — esta é a natureza da `ForeignKey` field). Navegue de volta para a *Página inicial* e pressione o botão *Adicionar* associado para exibir a tela *Adicionar instância* 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.

![Admin Site - BookInstance Add](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_bookinstance_add.png)

Crie vários desses registros para cada um de seus livros. Defina o status como *Disponível* para pelo menos alguns registros e *Em empréstimo* para outros. Se o status **não** for *Disponível*, defina também uma *data de vencimento* futura.

É isso aí! Agora você aprendeu como configurar e usar o site de administração. Você também criou registros para `Book`, `BookInstance`, `Genre`, e `Author` que poderemos usar assim que criarmos nossas próprias visualizações e modelos.

Configuração Avançada
---------------------

O Django faz um bom trabalho ao criar um site de administração básico usando as informações dos modelos registrados:

* Cada modelo possui uma lista de registros individuais, identificados pela string criada com o método `__str__()` 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.
* 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.

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:

* List views:
    + Adicionar adicional fields/information exibido para cada registro.
    + 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).
    + Adicione opções adicionais ao menu de ações nas exibições de lista e escolha onde esse menu é exibido no formulário.
* Detail views
    + Escolha quais campos exibir (ou excluir), junto com sua ordem, agrupamento, se eles são editáveis, o widget usado, a orientação etc.
    + 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).

In this section we're going to look at a few changes that will improve the interface for our *LocalLibrary*, including adding more information to `Book` and `Author` model lists, and improving the layout of their edit views. We won't change the `Language` and `Genre` model presentation because they only have one field each, so there is no real benefit in doing so!

You can find a complete reference of all the admin site customisation choices in The Django Admin site (Django Docs).

### Registrando uma classe ModelAdmin

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.

Vamos começar com o `Author` model. Abra **admin.py** no aplicativo de catálogo (/locallibrary/catalog/admin.py). Comente o seu registro original (prefixo com um #) para o `Author` model:

```js
# admin.site.register(Author)
```

Agora adicione um novo `AuthorAdmin` e registre como mostrado abaixo.

```python
# Define the admin class
class AuthorAdmin(admin.ModelAdmin):
    pass

# Register the admin class with the associated model
admin.site.register(Author, AuthorAdmin)
```

Agora vamos adicionar as classes `ModelAdmin` para `Book`, e `BookInstance`. Precisamos novamente comentar os registros originais:

```js
# admin.site.register(Book)
# admin.site.register(BookInstance)
```

Agora, para criar e registrar os novos modelos; para o propósito desta demonstração, vamos usar o `@register` decorador para registrar os modelos (isso faz exatamente a mesma coisa que `admin.site.register()` sintaxe):

```python
# 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
```

Atualmente todas as nossas classes administrativas estão vazias (veja `pass`) então o comportamento do administrador não será alterado! Agora podemos estendê-los para definir nosso comportamento administrativo específico do modelo.

### Configure list views

A LocalLibrary atualmente lista todos os autores usando o nome do objeto gerado a partir do método `__str__()` 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 list\_display para adicionar campos adicionais à vista.

Substitua seu`AuthorAdmin` class com o código abaixo. Os nomes de campo a serem exibidos na lista são declarados em uma *tupla* na ordem requerida, conforme mostrado (esses são os mesmos nomes especificados em seu modelo original).

```python
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('last\_name', 'first\_name', 'date\_of\_birth', 'date\_of\_death')
```

Agora navegue até a lista de autores em seu site. Os campos acima devem agora ser exibidos, assim:

![Admin Site - Improved Author List](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_improved_author_list.png)

Para o nosso `Book` model nós vamos adicionalmente exibir o `author` e `genre`. O `author` é uma variável `ForeignKey` (um-para-um) relacionamento, e assim será representado pelo valor `__str__()` para o registro associado. Substitua o `BookAdmin` class com a versão abaixo.

```python
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'display\_genre')
```

Infelizmente não podemos especificar diretamente a variável genre na `list_display` porque é um `ManyToManyField`(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 `display_genre` para obter as informações como uma string (esta é a função que chamamos acima; vamos defini-lo abaixo).

**Nota:** Nota: Obtendo o `genre` 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 *Apagar* ao lado de cada item da lista.

Adicione o seguinte código ao seu `Book` model (**models.py**). Isso cria uma string a partir dos três primeiros valores da variavel `genre` (se existirem) e cria um `short_description` que pode ser usado no site administrativo para esse método.

```python
    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'
```

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:

![Admin Site - Improved Book List](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_improved_book_list.png)

O `Genre` model (e a `Language` model, se você definiu um) ambos têm um único campo, portanto, não faz sentido criar um modelo adicional para exibir campos adicionais.

**Nota:** Nota: Vale a pena atualizar o`BookInstance` 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!

### Adicionando list filters

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 `list_filter`. Substitua sua atual `BookInstanceAdmin` class com o fragmento de código abaixo.

```python
class BookInstanceAdmin(admin.ModelAdmin):
    list_filter = ('status', 'due\_back')
```

A visualização de lista agora incluirá uma caixa de filtro à direita. Observe como você pode escolher datas e status para filtrar os valores:

![Admin Site - BookInstance List Filters](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_improved_bookinstance_list_filters.png)

### Organizando o layout da detail view

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.

**Nota:** Nota: Os modelos *LocalLibrary* são relativamente simples, portanto não é necessário alterar o layout; No entanto, faremos algumas alterações, só para mostrar como.

#### Controlando quais campos são exibidos

Atualize seu `AuthorAdmin` class para adicionar a linha `fields`, como mostrado abaixo (em negrito):

```python
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('last\_name', 'first\_name', 'date\_of\_birth', 'date\_of\_death')
    fields = ['first\_name', 'last\_name', ('date\_of\_birth', 'date\_of\_death')]
```

O atributo `fields` 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).

No seu site, acesse a visualização de detalhes do autor. Agora, ele deve aparecer como mostrado abaixo:

![Admin Site - Improved Author Detail](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_improved_author_detail.png)

**Nota:** Nota: você também pode usar o atributo `exclude` para declarar uma lista de atributos a serem excluídos do formulário (todos os outros atributos no modelo serão exibidos).

#### Seccionando a detail view

Você pode adicionar "seções" para agrupar informações de modelo relacionadas dentro do formulário detalhado, usando o atributo fieldsets.

Na `BookInstance` model temos informações relacionadas ao que o livro é (i.e. `name`, `imprint`, e `id`) e quando estará disponível (`status`, `due_back`). Podemos adicionar estes em diferentes seções, adicionando o texto em negrito para o nosso `BookInstanceAdmin` class.

```python
@admin.register(BookInstance)
class BookInstanceAdmin(admin.ModelAdmin):
    list_filter = ('status', 'due\_back')

    fieldsets = (
        (None, {
            'fields': ('book', 'imprint', 'id')
        }),
        ('Availability', {
            'fields': ('status', 'due\_back')
        }),
    )
```

Cada seção tem seu próprio título (ou `None`,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.

Agora, navegue até uma visualização de instância do livro em seu website; o formulário deve aparecer como mostrado abaixo:

![Admin Site - Improved BookInstance Detail with sections](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_improved_bookinstance_detail_sections.png)

### Edição inline de registros associados

À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.

Você pode fazer isso declarando inlines, do tipo TabularInline (horizonal layout) or StackedInline (layout vertical, assim como o layout do modelo padrão). Você pode adicionar ao `BookInstance` informações inline para o nosso `Book` detalhe, adicionando as linhas abaixo em negrito perto do seu `BookAdmin`:

```python
class BooksInstanceInline(admin.TabularInline):
    model = BookInstance

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'display\_genre')
    inlines = [BooksInstanceInline]
```

Agora navegue até uma view pala um `Book` 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):

![Admin Site - Book with Inlines](/pt-BR/docs/Learn/Server-side/Django/Admin_site/admin_improved_book_detail_inlines.png)

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 TabularInline para maiores informações).

**Nota:** 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 **Add another Book instance** , ou poder listar apenas `BookInstance`s como links não legíveis daqui. A primeira opção pode ser feita configurando atributo `extra` para 0 no `BooksInstanceInline` model, tente você mesmo.

Desafie-se
----------

Aprendemos muito nesta seção, então agora é hora de você tentar algumas coisas.

1. Para a *listview* `BookInstance`, adicione o código para exibir o livro, o status, a data de devolução e o id (em vez do texto padrão `__str__()`).
2. Adicione uma listagem *inline* de itens `Book` para a lista detalhada de `Author` usando a mesma abordagem que fizemos para `Book`/`BookInstance`.
Resumo
------

É 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 *views* e *templates*.

Leitura adicional
-----------------

* Escrevendo seu primeiro app Django, parte 2: Apresentando o Django Admin (Django docs)
* O Django Admin site (Django Docs)
* Anterior
* Menu: Django
* Próxima


Configurando um ambiente de desenvolvimento Django - Aprendendo desenvolvimento web

Configurando um ambiente de desenvolvimento Django
==================================================

* Anterior
* Menu: Django
* Próxima

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.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Saber como usar um teminal / linha de comando. Saber instalar softwares
 em seu sistema operacional.
  |
| Objetivo: |
 Ter uma ambiente de desenvolvimento Django (2.0) operando em seu
 computador.
  |

Visão geral do ambiente de desenvolvimento Django
-------------------------------------------------

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 *recomendado* de instalar o ambiente Django no Ubuntu, macOS e Windows e como testar.

### O que é o ambiente de desenvolvimento Django?

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

A principal ferramenta que Django fornece é um conjunto de scripts Python para criar e trabalhar com projetos Django, junto com um simples *webserver de desenvolvimento* 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.

Existem outras ferramentas secundárias que fazem parte do ambiente de desenvolvimento que não cobriremos aqui. Isso inclui coisas como um editor de texto (en-US) ou IDE para edição de código, e uma ferramenta pra gerenciamento do controle de origem de códigos (como o Git) 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.

### Quais são as opções de instalação do Django?

Django é extremamente flexível em termos de como e onde ele pode ser instalado e configurado. Django pode:

* Ser instalado em diferentes sistemas operacionais.
* Ser instalado pelo código-fonte, pelo Python Package Index (PyPi) e, em muitos casos, pelo aplicativo gerenciador de pacotes do computador host.
* Ser configurado para uso de um dos vários bancos de dados, que também podem ser instalados e configurados separadamente.
* Operar no ambiente principal do sistema Python ou em ambientes virtuais Python, separadamente.

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.

**Nota:** Outras possíveis opções de instalação são cobertas pela documentação oficial do Django. Nós linkamos os documents adequados abaixo.

#### Quais sistemas operacionais suportam Django?

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.

Neste artigo, iremos fornecer instruções para Windows, macOS a Linux/Unix.

#### Qual versão de Python deve ser usada?

Nós recomendamos que use a mais recente versão disponível — no momento que escrevo é Python 3.7.1.

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).

**Nota:** 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).

#### Onde posso baixar o Django?

Existem três lugares para fazer o download do Django:

* Python Package Repository (PyPi), usando o comando *pip*. Esta é a melhor forma de conseguir a última versão estável do Django.
* 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).
* 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.

Este artigo mostra a instalação pelo Pypi, pois queremos a última versão estável do Django.

#### Qual banco de dados?

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á problemas em potencial que é melhor evitar).

Neste artigo (e na maior parte deste módulo) nós usaremos o banco de Dados *SQLite*, 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.

**Nota:** 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.

#### Instalar em todo o sistema ou em um ambiente virtual Python?

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.

**Nota:** 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).

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.

Pensando nisso, desenvolvedores experientes de Python/Django normalmente executam apps Python dentro de um *ambiente virtual Python* 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!

Esse módulo assume que você instalou o Django em um ambiente virtual, nós iremos mostrá-lo como fazer isso logo abaixo.

Instalando Python 3
-------------------

Você deve ter Python instalado em seu sistema operacional para usar Django. Se você estiver usando *Python 3*, também precisará da ferramenta Python Package Index — *pip3* — que é usada para administrar (instalar, editar, remover) pacotes/bibliotecas Python usadas por Django e seus outros aplicativos Python.

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).

**Nota:** 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 https://www.python.org/downloads/ e instalá-los usando o método específico da plataforma em questão.

### Ubuntu 18.04

Ubuntu Linux 18.04 LTS inclui Python 3.6.6 por padrão. Você pode confirmar isso executando o seguinte comando no Terminal:

```bash
python3 -V
 Python 3.6.6
```

Contudo, o Python Package Index, que você precisará para instalar pacotes para Python 3 (incluindo Django), **não** está disponível por padrão. Você pode instalar pip3 pelo Terminal usando:

```bash
sudo apt install python3-pip
```

### macOS

macOS "El Capitan" e outras versões mais recentes não incluem Python 3. Você pode confirmar isto executando os comandos abaixo no Terminal:

```bash
python3 -V
 -bash: python3: command not found
```

Você pode instalar Python 3 (com a ferramenta pip3) facilmente em python.org:

1. Baixe o instalador exigido:
    1. Acesse https://www.python.org/downloads/
    2. Selecione o botão **Download Python 3.7.1** (o número exato da versão menor pode diferir).
2. Localize o arquivo usando *o Finder*, e clique duplo no arquivo do pacote. Siga os passos da instalação dos prompts.

Agora você pode confirmar se tudo deu certo checando o *Python 3* como mostrado abaixo:

```bash
python3 -V
 Python 3.7.1
```

Você pode checar se *pip3* está instalado listando todos os pacotes disponíveis.

```bash
pip3 list
```

### Windows 10

Windows não inclui Python por padrão, mas você pode instalá-lo facilmente (com a ferramenta *pip3*) em python.org:

1. Baixe o instalador exigido:
    1. Acesse https://www.python.org/downloads/
    2. Selecione o botão **Download Python 3.7.1** (o número exato da versão menor pode diferir).
2. Instale Python com um clique duplo no arquivo baixado e siga a instalação dos prompts.
3. Tenha certeza que a caixa "Add Python to PATH" está checada.

Você pode verificar se o Python 3 foi instalado colocando o seguinte texto no Prompt de Comando

```bash
py -3 -V
 Python 3.7.1
```

O instalador do Windows incorpora *pip3* (o administrador de pacotes Python) por padrão. Você pode facilmente listar os pacotes instalados com o comando abaixo:

```bash
pip3 list
```

**Nota:** 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.

Usando Django em um ambiente virtual Python
-------------------------------------------

As bibliotecas que nós iremos usar para criar nossos ambientes virtuais são virtualenvwrapper (Linux e macOS) e virtualenvwrapper-win (Windows), sendo que ambas usam a ferramenta virtualenv (en-US). as bibliotecas criam uma interface consistente para manusear interfaces em todas plataformas;

### Instalando o software de ambiente virtual

#### Instalação do ambiente virtual no Ubuntu

Após instalar Python e pip, você pode instalar *virtualenvwrapper* (que inclui*virtualenv*). O guia oficial para a instalação pode ser encontrado aqui, ou siga as instruções abaixo.

Instale a ferramenta usando *pip3*:

```bash
sudo pip3 install virtualenvwrapper
```

Em seguida, adicione as linhas abaixo no fim de seu arquivo shell startup (este é um arquivo oculto nomeado **.bashrc** 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.

```bash
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
```

**Nota:** As variáveis `VIRTUALENVWRAPPER_PYTHON` e `VIRTUALENVWRAPPER_VIRTUALENV_ARGS` apontam para a localização em uma instalação normal de Python 3, e `source /usr/local/bin/virtualenvwrapper.sh` aponta para a localização normal do script `virtualenvwrapper.sh` Se *virtualenv* 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).

Você pode encontrar a localização correta no seu sistema usando os comandos `which virtualenvwrapper.sh` e `which python3`.

Recarregue o arquivo de startup executando o seguinte comando no Terminal:

```bash
source ~/.bashrc
```

Após executar o comando, você deveria ver scripts como esses:

```bash
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
```

Agora você pode criar um novo ambiente virtual com o comando `mkvirtualenv`.

#### Instalação do ambiente virtual no macOS

Instalar *virtualenvwrapper* no macOS é quase a mesma coisa que instalar no Ubuntu (novamente, você pode seguir as instruções do guia oficial de instalação ou as instruções abaixo).

Instale *virtualenvwrapper* (e *virtualenv*) usando *pip* como abaixo.

```bash
sudo pip3 install virtualenvwrapper
```

Então adicione as seguintes linhas no arquivo de startup do seu shell.

```bash
export WORKON\_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER\_PYTHON=/usr/bin/python3
export PROJECT\_HOME=$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh
```

**Nota:** A variável `VIRTUALENVWRAPPER_PYTHON` aponta para uma localização em uma instalação normal de Python 3, e `source /usr/local/bin/virtualenvwrapper.sh` aponta para a localização comum do script `virtualenvwrapper.sh`. Se *virtualenv* 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).

Por exemplo, uma instalação teste no macOS termina com as seguintes linhas no arquivo de startup:

```bash
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
```

Você pode encontrar a localização correta no seu sistema usando os comandos `which virtualenvwrapper.sh` e `which python3`.

São as mesmas linhas digitadas no Ubuntu, mas o arquivo de startup é diferente nomeado como **.bash\_profile**, oculto no seu diretório home.

**Nota:** Se você não acha o arquivo **.bash\_profile** pelo finder, você pode abir pelo terminal usando o *nano*.

Os comandos são como esses:
```

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.
```

Atualize o arquivo de startup fazendo o seguinte chamado no terminal:

```bash
source ~/.bash_profile
```

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 `mkvirtualenv`.

#### Instalação do ambiente virtual no Windows 10

Instalar virtualenvwrapper-win é ainda mais simples que instalar *virtualenvwrapper*, 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.
```

pip3 install virtualenvwrapper-win
```

Agora você pode criar um novo ambiente virtual com o comando `mkvirtualenv`.

### Criando um ambiente virtual

Uma vez que você tenha instalado *virtualenvwrapper* ou *virtualenvwrapper-win*, trabalhar com ambientes virtuais é bem parecido em todas as plataformas.

Agora você pode criar um novo ambiente virtual com o comando `mkvirtualenv`. 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).
```

$ 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:~$
```

Agora que você está em um ambiente virtual, você pode instalar Django e iniciar o desenvolvimento.

**Nota:** 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.

### Usando um ambiente virtual

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):

* `deactivate` — Encerra o ambiente virtual Python corrente.
* `workon` — Lista ambientes virtuais disponíveis.
* `workon name_of_environment` — Ativa o ambiente virtual Python especificado.
* `rmvirtualenv name_of_environment` — Remove o ambiente especificado.
Instalando o Django
-------------------

Após criar um ambiente virtual e usado o comando `workon` para ativá-lo, você pode usar *pip3* para instalar o Django.

```bash
pip3 install django
```

Você pode testar a instalação do Django executando o seguinte comando (isso apenas testa se o Python pode achar o módulo Django):

```bash
# Linux/macOS
python3 -m django --version
 2.1.5

# Windows
py -3 -m django --version
 2.1.5
```

**Nota:** Se o comando Windows acima não mostrar um módulo django, tente:

```bash
py -m django --version
```

No Windows, os scripts *Python 3* são iniciados prefixando o comando com `py -3`, embora isso possa variar de acordo com sua instalação. Tente omitir o modificador `-3` se você encontrar algum problema com os comandos. No Linux/macOS, o comando é `python3`.

**Aviso:** **Importante**: O resto deste **módulo** usa o comando *Linux* para chamar o Python 3 (`python3`). Se você está usando o Windows, substitua o prefixo por: `py -3`

Testando sua instalação
-----------------------

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.

```bash
mkdir django_test
cd django_test
```

Agora você pode criar um novo site chamado "*mytestsite*" usando a ferramenta **django-admin**. Após criar o site você pode navegar dentro da pasta onde encontrará o script principal para gerenciar projetos, nomeado **manage.py**.

```bash
django-admin startproject mytestsite
cd mytestsite
```

Nós podemos rodar o *web server de desenvolvimento* dentro dessa pasta usando o **manage.py** e o comando `runserver`, como mostrado.

```bash
$ 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.
```

**Nota:** Acima foi mostrado o comando em Linux/macOS. Você já pode ignorar o aviso sobre "15 unapplied migration(s)"!

 Uma vez que o servidor está operando, você pode acessar o site colocando a seguinte URL no seu navegador local:`http://127.0.0.1:8000/`. Você deveria ver um site como esse:

 ![Django Skeleton App Homepage - Django 2.0](/pt-BR/docs/Learn/Server-side/Django/development_environment/django_skeleton_website_homepage_2_1.png)

Resumo
------

Agora você tem um ambiente de desenvolvimento em Django funcionando em seu computador.

Na seção *Testando sua instalação* você viu brevemente como criar um website Django usando `django-admin startproject`, e executá-lo em seu navegador usando um web server de desenvolvimento (`python3 manage.py runserver`). No próximo artigo nós iremos expandir esse processo, construindo uma aplicação web simples, mas completa.

Veja também
-----------

* Guia de Instalação Rápida (documentação Django)
* Como instalar Django — Guia completo (documentação Django) - inclui informações para remover o Django
* Como instalar Django no Windows (documentação Django)
* Anterior
* Menu: Django
* Próxima