---
title: "Escrevendo sua primeira aplicação Django, parte 2"
version: 1.11
locale: pt-br
source: https://docs.djangoproject.com/pt-br/1.11/intro/tutorial02/
canonical: https://djangodocs.dev/pt-br/1.11/intro/tutorial02/
---
# Escrevendo sua primeira aplicação Django, parte 2

Este tutorial inicia onde [Tutorial 1](/pt-br/1.11/intro/tutorial01/) termina. Iremos configurar um banco de dados, criar seu primeiro modelo, e ter uma rápida introdução ao admin site do Django automaticamente gerado.

## Configuração do banco de dados

Agora, abra o `mysite/settings.py`. Ele é um módulo normal do Python com variáveis de módulo representando as configurações do Django.

Por padrão, a configuração usa o SQLite. Se você é novo com banco de dados, ou se estiver somente interessado em experimentar o Django, esta á maneira mais simples. SQLite está incluso no Python, de modo que você não precisa instalar nada a mais para ter o banco de dados. Contudo, quando iniciar seu primeiro projeto real, talvez queira usar um banco de dados mais escalável como o PostgreSQL, para evitar problemas com a troca do banco de dados no caminho.

Se você quiser usar outro banco de dados, instale o de acordo [database bindings](/pt-br/1.11/topics/install/#database-installation) e altere os seguinte parâmetros no item [`DATABASES`](/pt-br/1.11/ref/settings/#std-setting-DATABASES) `'default'` de acordo com o seu banco de dados.

- [`ENGINE`](/pt-br/1.11/ref/settings/#std-setting-DATABASE-ENGINE) – ou mesmo  `'django.db.backends.sqlite3'`, `'django.db.backends.postgresql'`, `'django.db.backends.mysql'`, ou `'django.db.backends.oracle'`. Outros backends são [also available](/pt-br/1.11/ref/databases/#third-party-notes).
- [`NAME`](/pt-br/1.11/ref/settings/#std-setting-NAME) – O nome do seu banco de dados, se você estiver usando SQLite, o banco de dados será uma arquivo no seu computador; neste caso, [`NAME`](/pt-br/1.11/ref/settings/#std-setting-NAME) deve ser o caminho completo, incluindo o nome, para este arquivo. O valor padrão `os.path.join(BASE_DIR, 'db.sqlite3')`, ira criar este arquivo no diretorio do seu projeto.

Caso não use o SQLite como banco de dados, configurações adicionais como [`USER`](/pt-br/1.11/ref/settings/#std-setting-USER), [`PASSWORD`](/pt-br/1.11/ref/settings/#std-setting-PASSWORD), e [`HOST`](/pt-br/1.11/ref/settings/#std-setting-HOST) deverão ser adicionadas. Para mais detalhes, veja a referência na documentação para [`DATABASES`](/pt-br/1.11/ref/settings/#std-setting-DATABASES).

> **Para fins diferentes da base de dados SQLite**
>
> Caso use um banco de dados além do SQLite, tenha certeza que o banco de dados foi criado até este ponto. Faça isso com “`CREATE DATABASE database_name;`” dentro do prompt interativo do seu banco de dados.
>
> Também se certifique que o “database user” indicado em `mysite/settings.py` tenha a permissão  “create database”. Isso permite a criação automática de  [test database](/pt-br/1.11/topics/testing/overview/#the-test-database) o qual será necessário e um tutorial mais adiante.
>
> Se você está utilizando SQLite você não precisa criar nada de antemão - o arquivo do banco de dados será criado automaticamente quando ele for necessário.

Enquanto estiver editando `mysite/settings.py`, mude [`TIME_ZONE`](/pt-br/1.11/ref/settings/#std-setting-TIME_ZONE) para o seu fuso horário.

Também observe a configuração do
[`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS) na parte superior do arquivo. Ela possui os nomes de todas as aplicações Django ativas para essa instância do Django. Aplicações podem ser usadas em múltiplos projetos, e você pode empacotá-las e distribuí-las para uso por outros em seus projetos.

Por padrão, o [`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS) contém as seguintes aplicações, que vêm com o Django:

- [`django.contrib.admin`](/pt-br/1.11/ref/contrib/admin/#module-django.contrib.admin) – O admin site. Irá usar isso em breve.
- [`django.contrib.auth`](/pt-br/1.11/topics/auth/#module-django.contrib.auth) – Um sistema de autenticação.
- [`django.contrib.contenttypes`](/pt-br/1.11/ref/contrib/contenttypes/#module-django.contrib.contenttypes) – Um framework para tipos de conteúdo.
- [`django.contrib.sessions`](/pt-br/1.11/topics/http/sessions/#module-django.contrib.sessions) – Um framework de sessão.
- [`django.contrib.messages`](/pt-br/1.11/ref/contrib/messages/#module-django.contrib.messages) – Um framework de envio de mensagem.
- [`django.contrib.staticfiles`](/pt-br/1.11/ref/contrib/staticfiles/#module-django.contrib.staticfiles) – Um framework para gerenciamento de arquivos estáticos.

Estas aplicações são incluídas por padrão como uma conveniência para o caso comum.

Algumas dessas aplicações fazem uso de pelo menos uma tabela no banco de dados, assim sendo, nós precisamos criar as tabelas no banco de dados antes que possamos
utilizá-las. Para isso rode o seguinte comando:

```console
$ python manage.py migrate
```

O comando [`migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate) verifica a configuração em [`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS) e cria qualquer tabela do banco de dados necessária de acordo com as configurações do banco de dados no seu arquivo `mysite/settings.py` e as migrações que venham com a app (cobriremos isso mais tarde). É mostrado uma mensagem para cada migração que foi aplicada. Se lhe interessar, execute cliente de linha de comando para seu banco de dados e dgite `\dt` (PostgreSQL), `SHOW TABLES;` (MySQL), `.schema` (SQLite), ou `SELECT TABLE_NAME FROM USER_TABLES;` (Oracle) para mostrar as tabelas mostradas pelo Django.

> **Para os minimalistas**
>
> Como dissemos acima, as aplicações padrão são incluídas para casos comuns, mas nem todo mundo precisa delas. Se você não precisa de nenhuma delas, sinta-se livre para comentar ou deletar a(s) linha(s) apropriada(s) do   [`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS) antes de rodar o [`migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate). O comando [`migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate) irá executar as migrações apenas para as aplicações que estiverem no [`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS).

## Criando modelos

Agora vamos definir seus modelos – essencialmente, o layout do banco de dados, com metadados adicionais.

> **Filosofia**
>
> Um model é a única e definitiva fonte de verdade sobre seus dados. Ele contém os campos essenciais e os comportamentos para os dados que você estiver   armazenando. O Django segue o [princípio DRY](/pt-br/1.11/misc/design-philosophies/#dry). O objetivo é definir seu modelo de dados em um único local e automaticamente derivar coisas a partir dele.
>
> Isso inclui as migrações - ao contrário em Ruby on Rails, por exemplo, as migrações são inteiramente derivada de seu arquivo de modelos, e são essencialmente apenas uma história que o Django pode avançar para atualizar o esquema de banco de dados para coincidir com seus modelos atuais.

Em nossa simples aplicação de enquete, nós iremos criar dois modelos: `Question` e `Choice`. Uma `Question` tem uma pergunta e uma data de publicação. Uma `Choice`  tem dois campos: o texto da escolha e um totalizador de votos. Cada `Choice` é associada a uma `Question`.

Esses conceitos são representados por simples classes Python. Edite o arquivo `polls/models.py` de modo que fique assim:

*polls/models.py*

```
from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
```

O código é auto-explicativo. Cada model é representado por uma classe derivada da classe [`django.db.models.Model`](/pt-br/1.11/ref/models/instances/#django.db.models.Model). Cada model possui um número de atributos de classe, as quais por sua vez representam campos de banco de dados no model.

Cada campo é representado por uma instância de uma classe [`Field`](/pt-br/1.11/ref/models/fields/#django.db.models.Field) – e.g., [`CharField`](/pt-br/1.11/ref/models/fields/#django.db.models.CharField) para campos do tipo caractere e [`DateTimeField`](/pt-br/1.11/ref/models/fields/#django.db.models.DateTimeField) para
data/hora. Isto diz ao Django qual tipo de dado cada campo contém.

O nome de cada instância [`Field`](/pt-br/1.11/ref/models/fields/#django.db.models.Field) (e.g. `question_text` ou `pub_date`) é o nome do campo, em formato amigável para a máquina. Você irá usar este valor no seu código Python, e seu banco de dados irá usá-lo como nome de coluna.

Você pode usar um argumento opcional na primeira posição de um [`Field`](/pt-br/1.11/ref/models/fields/#django.db.models.Field) para designar um nome legível por seres humanos o qual será usado em uma série de partes introspectivas do Django, e também servirá como documentação. Se esse argumento não for fornecido, o Django utilizará o nome legível pela máquina. Neste exemplo nós definimos um nome legível por humanos apenas para `Question.pub_date`. Para todos os outros campos neste model, o nome legível pela máquina será utilizado como nome legível por humanos.

Algumas classes de [`Field`](/pt-br/1.11/ref/models/fields/#django.db.models.Field) possuem elementos obrigatórios.  O [`CharField`](/pt-br/1.11/ref/models/fields/#django.db.models.CharField), por exemplo, requer que você informe a ele um `max_length` que é usado não apenas no esquema do banco de dados, mas na validação, como nós veremos em breve.

Um [`Field`](/pt-br/1.11/ref/models/fields/#django.db.models.Field) pode ter varios argumentos opcionais; neste caso, nos definimos [`default`](/pt-br/1.11/ref/models/fields/#django.db.models.Field.default) o valor de `votes` para 0.

Finalmente, note que uma relação foi criada, usando [`ForeignKey`](/pt-br/1.11/ref/models/fields/#django.db.models.ForeignKey). Isso dia ao Django que cada `Choice` está relacionada a uma única `Question`. O Django suporta todos os relacionamentos comuns de um banco de dados: muitos-para-um, muitos-para-muitos e um-para-um

## Ativando modelos

Aquela pequena parte do model fornece ao Django muita informação. Com ela o Django é capaz de:

- Criar um esquema de banco de dados (instruções `CREATE TABLE`) para a aplicação.
- Criar uma API de acesso a banco de dados para acessar objetos `Question` e `Choice`.

Mas primeiro nós precisamos dizer ao nosso projeto que a aplicação `polls` está instalada.

> **Filosofia**
>
> Aplicações Django são “plugáveis”: Você pode usar uma aplicação em múltiplos projetos, e você pode distribuir aplicações, porque elas não precisam ser atreladas a uma determinada instalação do Django.

Para incluir a aplicação no nosso projeto, precisamos adicionar a referência à classe de configuração da aplicação na definição do [`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS) . A classe ```PollsConfig``está no arquivo  :file:`polls/apps.py`, então seu caminha pontuado é ``'polls.apps.PollsConfig'```. Edite o arquivo `mysite/settings.py` e adicione aquele caminho com notação de ponto a definição do [`INSTALLED_APPS`](/pt-br/1.11/ref/settings/#std-setting-INSTALLED_APPS). Ficará parecido como aqui:

*mysite/settings.py*

```
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```

Agora o Django sabe que deve incluir a aplicação `polls`. Vamos rodar outro comando:

```console
$ python manage.py makemigrations polls
```

Você deverá ver algo similar ao seguinte:

```text
Migrations for 'polls':
  polls/migrations/0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice
```

Ao executar `makemigrations`, você está dizendo Django que você fez algumas mudanças em seus modelos (neste caso, você fez novas modificações) e que você gostaria que as alterações sejam armazenadas como uma *migração*.

As migrações são como o Django armazena as alterações nos seus modelos (e, portanto, seu esquema de banco de dados) - eles são apenas arquivos no disco. Você pode ler a migração para o novo modelo, se quiser; é o arquivo `polls/migrations/0001_initial.py`. Não se preocupe, você não precisa lê-los cada vez Django cria um, mas eles são projetados para ser editável no caso de você queira ajustar manualmente como Django muda as coisas.

Existe um comando que vai rodar as migrações para você e gerenciar o esquema do banco de dados automaticamente -  que é chamado [`migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate), e nós vamos chegar a ele em um momento - mas primeiro vamos ver qual SQL está migração vai rodar. O comando [`sqlmigrate`](/pt-br/1.11/ref/django-admin/#django-admin-sqlmigrate) recebe o nome da migração e o seu SQL.

```console
$ python manage.py sqlmigrate polls 0001
```

Você deve ver algo semelhante ao seguinte (reformatamos para facilitar a leitura):

```sql
BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;

COMMIT;
```

Note o seguinte:

- A saída exata irá variar dependendo do banco de dados que você está utilizando.
- Os nomes das tabelas são gerados automaticamente combinando o nome da aplicação (`polls`) e o nome em minúsculas do model – `question` e `choice`. (Você pode alterar esse comportamento.)
- Chaves primárias (IDs) são adicionadas automaticamente. (Você também pode modificar isso.)
- Por convenção, o Django adiciona `"_id"` ao nome do campo de uma chave estrangeira. (Sim, você pode alterar isso, como quiser.)
- O relacionamento da chave estrangeira é feito explicitamente por uma instrução `FOREIGN KEY`. Não se preocupe sobre partes `DEFERRABLE`; Está apenas instruindo o PostgreSQL para não forçar a criação da chave estrangeira até o fim da transação.
- Isto é atrelado ao banco que você está usando, então a utilização de campos específicos do banco de dados como `auto_increment` (MySQL), `serial` (PostgreSQL), ou `integer primary key` (SQLite) é feita para você automaticamente. O mesmo ocorre com as aspas dos nomes de campos – e.g., usando aspas duplas ou aspas simples.
- O comando [`sqlmigrate`](/pt-br/1.11/ref/django-admin/#django-admin-sqlmigrate) na realidade não roda o SQL no seu banco de dados - ele apenas o exibe na tela para que você saiba qual SQL o Django acha que é necessário. É útil para verificar o que Django vai fazer ou se você tem administradores de bancos de dados que necessitam dos scripts SQL para mudanças.

Se você tiver interesse, você pode rodar [`python manage.py check`](/pt-br/1.11/ref/django-admin/#django-admin-check); Ele checa por problemas no seu projeto sem criar migrations ou tocar seu banco de dados.

Agora rode o [`migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate) novamente para criar essas tabelas dos modelos no seu banco de dados:

```console
$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK
```

O comando [`migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate) pega todas as migrações que ainda não foram aplicadas (Django rastreia quais foram aplicadas usando uma tabela especial em seu banco de dados chamada `django_migrations`) e aplica elas contra seu banco de dados - essencialmente, sincronizando as alterações feitas aos seus modelos com o esquema no banco de dados.

Migrações são muito poderosas e permitem que você altere seus modelos ao longo do tempo, à medida que desenvolve o seu projeto, sem a necessidade de remover o seu banco de dados ou tabelas e criar de novo - ele é especializado em atualizar seu banco de dados ao vivo, sem perda de dados. Nós vamos cobri-los com mais profundidade em uma parte posterior do tutorial, mas para agora, lembre-se deste guia de três passos para fazer mudanças nos seus modelos:

- Mude seus modelos (em `models.py`).
- Rode [`python manage.py makemigrations`](/pt-br/1.11/ref/django-admin/#django-admin-makemigrations) para criar migrações para suas modificações
- Rode [`python manage.py migrate`](/pt-br/1.11/ref/django-admin/#django-admin-migrate) para aplicar suas modificações no banco de dados.

A razão de haver comandos separados para criar e aplicar as migrações é porque você vai submeter migrações para o seu sistema de controle de versão e enviá-los com sua aplicação; eles não só fazem o seu desenvolvimento mais fácil, eles também são utilizáveis ​​por outros desenvolvedores e em produção.

Leia a [documentação do django-admin](/pt-br/1.11/ref/django-admin/) para informações completas sobre o que o utilitário `manage.py` pode fazer.

## Brincando com a API

Agora vamos dar uma passada no shell interativo do Python e brincar um pouco com a API livre que o Django dá a você. Para invocar o shell do Python, use esse comando:

```console
$ python manage.py shell
```

Nós usaremos isso em vez de simplesmente digitar “python”, porque o `manage.py` configura a variável de ambiente `DJANGO_SETTINGS_MODULE`, O que da ao Django o caminho de importação Python do arquivo `mysite/settings.py`.

> **Ignorando manage.py**
>
> Se você optar por não usar o `manage.py`, não há problemas. Apenas configure a variável de ambiente   [`DJANGO_SETTINGS_MODULE`](/pt-br/1.11/topics/settings/#envvar-DJANGO_SETTINGS_MODULE) para `mysite.settings`, Inicie um shell Python puro e e configure o Django:
>
> ```pycon
> >>> import django
> >>> django.setup()
> ```
>
> Se levantar um  [`AttributeError`](https://docs.python.org/3/library/exceptions.html#AttributeError), Você provavelmente está usando uma versão do Django que funciona com está versão do tutorial. Você vai querer quer mudar para um tutorial mais velho ou a versão mais recente do Django.
>
> Você deve rodar `python` a partir do mesmo diretório que `manage.py` está, ou garantir que este diretório está no cominho do Python, e assim `import mysite` funcionara.
>
> Para mais informações sobre isso tudo, veja a [documentação do django-admin](/pt-br/1.11/ref/django-admin/).

Assim que você estiver no shell, explore a [API de banco de dados](/pt-br/1.11/topics/db/queries/):

```
>>> from polls.models import Question, Choice   # Import the model classes we just wrote.

# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>

# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# Save the object into the database. You have to call save() explicitly.
>>> q.save()

# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> q.id
1

# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()

# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object>]>
```

Espere um pouco. `<Question: Question object>` é uma representação totalmente inútil desse objeto. Vamos corrigir isso editando o model da `Question` (no arquivo `polls/models.py`) e adicionando um método [`__str__()`](/pt-br/1.11/ref/models/instances/#django.db.models.Model.__str__) a ambos `Question` e `Choice`:

*polls/models.py*

```
from django.db import models
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible  # only if you need to support Python 2
class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

@python_2_unicode_compatible  # only if you need to support Python 2
class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text
```

É importante adicionar métodos [`__str__()`](/pt-br/1.11/ref/models/instances/#django.db.models.Model.__str__) aos seus models, não apenas para sua própria conveniência quando estiver lidando com o prompt interativo, mas também porque representações de objetos são usadas por todo projeto gerado automaticamente pelo Django.

Note que esses são métodos Python normais. Vamos adicionar um método personalizado, apenas para demonstração:

*polls/models.py*

```
import datetime

from django.db import models
from django.utils import timezone

class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
```

Note a adição de `import datetime` e `from django.utils import timezone`,  para referenciar o módulo padrão do Python [`datetime`](https://docs.python.org/3/library/datetime.html#module-datetime) e o modulo Django utilitário de fuso horário [`django.utils.timezone`](/pt-br/1.11/ref/utils/#module-django.utils.timezone), respectivamente. Se você não é familiar com o gerenciamento de fuso horário no  Python, você pode aprender mais no [documentação de suporte a fuso horários](/pt-br/1.11/topics/i18n/timezones/).

Salve essas mudanças e vamos iniciar uma nova sessão do shell interativo do Python rodando `python manage.py shell` novamente:

```
>>> from polls.models import Question, Choice

# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
```

Para mais informações sobre relacionamento de modelos, veja [Acessando objetos relacionados](/pt-br/1.11/ref/models/relations/). Para mais informação em como usar sublinhados duplos para pesquisa usando campos da API, veja [Pesquisa com campos](/pt-br/1.11/topics/db/queries/#field-lookups-intro). Para um detalhamento completo da API de banco de dados, veja nossa [referência à API de Banco de Dados](/pt-br/1.11/topics/db/queries/).

## Escrevendo sua primeira aplicação Django, parte 7

> **Filosofia**
>
> Gerar o site de administração para seu time ou clientes para adicionar, alterar, e deletar conteúdo é uma tarefa tediosa que não requer muita criatividade. Por essa razão, o Django automatiza totalmente a criação da interface de admin para os modelos.
>
> O Django foi desenvolvido em um ambiente de redação, onde havia uma clara separação entre “produtores de conteúdo” e o site “público”. Gerentes de site usam o sistema para adicionar notícias, eventos, resultado de esportes, etc, e o conteúdo é exibido no site público. O Django soluciona o problema de criar uma interface unificada para os administradores editarem o conteúdo.
>
> A administração não foi desenvolvida necessariamente para ser usada pelos visitantes do site, mas sim pelos gerentes.

### Criando um usuário administrador

Primeiro temos que criar um usuário que possa acessar o site de administração. Rode o seguinte comando:

```console
$ python manage.py createsuperuser
```

Digite seu nome de usuário desejado e pressione enter.

```text
Username: admin
```

Em seguida, será requisitado seu endereço de e-mail desejado:

```text
Email address: admin@example.com
```

O último passo é digitar sua senha. Você será solicitado que digite sua senha duas vezes, a segunda vez como uma confirmação da primeira.

```text
Password: **********
Password (again): *********
Superuser created successfully.
```

### Inicie o servidor de desenvolvimento

O site de administração vem ativado por padrão. Vamos iniciar o servidor de desenvolvimento e explora-lo.

Se o servidor não estiver sendo executado, inicie-o da seguinte forma:

```console
$ python manage.py runserver
```

Agora, abra o navegador de internet e vá para “/admin/” no seu domínio local – ex:, <http://127.0.0.1:8000/admin/>. Você deverá ver a tela de acesso:

![Django admin login screen](intro/_images/admin01.png)

Desde que [translation](/pt-br/1.11/topics/i18n/translation/) está habilitado por padrão, a tela de login talvez seja mostrada em sua própria língua, dependendo das configurações do seu browser a se o Django tem tradução para esta língua.

### Entre no site de administração

Agora, tente acessar o sistema com a conta de super usuário que criou no passo anterior.  Você deverá ver a página inicial do site de administração do Django:

![Django admin index page](intro/_images/admin02.png)

Você deverá ver alguns outros tipos de conteúdos editáveis, incluindo grupos e usuários. Estas  funcionalidades são fornecidas por mod:django.contrib.auth, o framework de autenticação fornecido pelo Django.

### Torne a aplicação de enquetes editável no site de administração

Mas onde está nossa aplicação de enquete? Ela não está visível na página principal do site de administração.

Apenas uma coisa a ser feita: Nós temos que dizer para o site de administração que os objetos `Question` possuem uma interface de administração.  Para fazer isto, crie um arquivo chamado `polls/admin.py`,  e edite para que se pareça com isto:

*polls/admin.py*

```
from django.contrib import admin

from .models import Question

admin.site.register(Question)
```

### Explore a funcionalidade de administração de graça

Agora que nós registramos `Question`, o Django sabe que ela deve ser exibida na página principal do site de administração:

![Django admin index page, now with polls displayed](intro/_images/admin03t.png)

Clique em “Questions”. Agora cocê está na página “change list” para “questions”. Essa página mostra todas as “questions” em seu banco de dados e lhe deixa escolher uma para alterar. Lá está a pergunta “What’s up?” que criamos anteriormente.

![Polls change list page](intro/_images/admin04t.png)

Clique na enquete “What’s up?” para editá-la:

![Editing form for question object](intro/_images/admin05t.png)

Coisas para observar aqui:

- O formulário é gerado automaticamente para o modelo `Question`.
- Os diferentes tipos de campos ([`DateTimeField`](/pt-br/1.11/ref/models/fields/#django.db.models.DateTimeField), [`CharField`](/pt-br/1.11/ref/models/fields/#django.db.models.CharField)) correspondem aos respectivos widgets HTML de inserção. Cada tipo de campo sabe como se exibir no site de administração do Django.
- Cada [`DateTimeField`](/pt-br/1.11/ref/models/fields/#django.db.models.DateTimeField) ganha um atalho JavaScript de graça. Datas possuem um atalho “Hoje” e um calendário popup, e horas têm um atalho “Agora” e um conveniente popup com listas de horas utilizadas comumente.

A parte inferior da página fornece uma série de opções:

- Salvar – Salva as alterações e retorna para a pagina lista de modificação para este tipo de objeto.
- Salvar e continuar editando – Salva as alterações e recarrega a página do site de administração para este objeto.
- Salvar e adicionar outro – Salva as informações e abre um novo formulário em branco para este tipo de objeto.
- Deletar – Exibe uma página de confirmação de exclusão.

Se o valor do “Date published” não bate com hora que a questão foi criada em [Tutorial 1](/pt-br/1.11/intro/tutorial01/), provavelmente quer dizer que foi esquecido de configurar o correto valor da configuração do [`TIME_ZONE`](/pt-br/1.11/ref/settings/#std-setting-TIME_ZONE). Altere isso, e recarregue a página e verifique se o calor correto aparece.

Altere a “Data de publicação” clicando nos atalhos “Hoje” e “Agora”. Em seguida, clique em “Salvar e continuar editando.” Então clique em “Histórico” no canto superior direito. Você verá uma página exibindo todas as alterações feitas neste objeto pelo site de administração do Django, com a hora e o nome de usuário da pessoa que fez a alteração:

![History page for question object](intro/_images/admin06t.png)

Quando estiver confortável com a “API” dos modelos e estiver familiarizado com o “admin site”, leia  [part 3 of this tutorial](/pt-br/1.11/intro/tutorial03/) para aprender sobre como adicionar mais “views”para nossa app “polls”.
