Vamos aprender pelo exemplo.
Ao longo desse tutorial nós iremos guiá-lo na criação de uma aplicação básica de enquete.
Ela irá consistir de duas partes:
- Um site público que deixa as pessoas verem as enquetes e votarem nelas.
- Um site de administração que deixa você adicionar, alterar e deletar enquetes.
Nós iremos assumir que você já tem o Django instalado. Você pode saber se o Django está instalado rodando o interpretador interativo do Python e digitando import django. Se esse comando rodar com sucesso, sem nenhum erro, o Django está instalado.
Onde conseguir ajuda:
Se você estiver tendo problemas no decorrer desse tutorial, por favor envie uma mensagem para django-users ou deixe-a em #django no irc.freenode.net e nós tentaremos ajudá-lo.
Se for a primeira vez que você está usando o Django você terá que preocupar-se com algumas configurações iniciais. A saber, você irá precisar auto-gerar algum código para estabelecer um projeto Django -- uma coleçao de configurações para uma instancia do Django, incluindo configuração do banco de dados, opções específicas do Django e configurações específicas da aplicação.
A partir da linha de comando, cd para o diretório onde você gostaria de armazenar seu código, então execute o comando django-admin.py startproject mysite. Isso irá criar o diretório mysite no seu diretório atual.
Permissões do Mac OS X
Se você estiver usando Mac OS X, você poderá ver a mensagem "permissão negada" quando você tentar rodar o django-admin.py startproject. Isso porque, em sistemas baseados no Unix como o OS X, um arquivo precisa ser marcado como "executável" antes que possa ser executado como um programa. Para fazer isso, abra o Terminal.app e navegue (usando o comando cd) até o diretório onde o django-admin.py está instalado, então rode o comando chmod +x django-admin.py.
Note
Você precisará evitar dar nomes a projetos que remetam a componentes internos do Python ou do Django. Particularmente, isso significa que você deve evitar usar nomes como django (que irá conflitar com o próprio Django) ou site (que irá conflitar com um pacote interno do Python).
(O django-admin.py deverá estar no caminho do seu sistema se você instalou o Django via python setup.py. Se ele não estiver no caminho, você pode encontrá- lo em site-packages/django/bin, onde site-packages é um diretório dentro da sua instalação do Python. Considere a possibilidade de criar um link simbólico para o django-admin.py a partir de algum lugar no seu caminho, como em /usr/ local/bin.)
Onde esse código deve morar?
Se você tem experiência prévia em PHP, você deve estar acostumado a colocar o código dentro da raiz da pasta de documentos do seu servidor Web (em um lugar como /var/www). Com o Django você não fará isto. Não é uma boa idéia colocar qualquer código Python na raiz da pasta de documentos do seu servidor Web, porque tem o possivel risco de pessoas conseguirem ver seu código através da Web. Isso não é bom para a segurança.
Coloque seu código em algum diretório fora da raiz da pasta de documentos, como em /home/mycode.
Vamos olhar o que o startproject criou:
mysite/
__init__.py
manage.py
settings.py
urls.py
Esses arquivos são:
- __init__.py: Um arquivo vazio que diz ao python que esse diretório deve ser considerado como um pacote Python. (Leia mais sobre pacotes na documentação oficial do Python se você for iniciante em Python.)
- manage.py: Um utilitário de linha de comando que permite a você interagir com esse projeto Django de várias maneiras.
- settings.py: Definições/configuração para esse projeto Django.
- urls.py: As declarações de URLs para esse projeto Django; uma "tabela de conteúdos" para o seu site movido a Django.
Vamos verificar se ele funciona. Vá para o diretório mysite, se você ainda não estiver nele, e rode o comando python manage.py runserver. Você irá ver a seguinte saída na sua linha de comando:
Validating models... 0 errors found. Django version 0.95, using settings 'mysite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
Você iniciou o servidor de desenvolvimento do Django, um servidor Web leve escrito puramente em Python. Nós incluímos ele com o Django, então você pode desenvolver coisas rapidamente, sem ter que lidar com a configuração de um servidor web de produção -- como o Apache -- até que você esteja pronto para a produção.
Agora é uma boa hora para anotar: NÃO use esse servidor em nada relacionado a um ambiente de produção. Seu objetivo é ser utilizado apenas durante o desenvolvimento. (Nós estamos no negócio de criar frameworks Web, não servidores Web.)
Agora que o servidor está rodando, visite http://127.0.0.1:8000/ com seu navegador Web. Você irá ver a página "Welcome to Django", em agradáveis tons de azul claro pastel. Ele funcionou!
Mudando a porta
Por padrão, o comando runserver inicia o servidor de desenvolvimento na porta 8000. Se você quer mudar a porta do servidor, passe ela como um argumento na linha de comando. Por exemplo, esse comando iniciará o servidor na porta 8080:
python manage.py runserver 8080
A documentação completa para o servidor de desenvolvimento está na documentação do django-admin.
Agora, edite o settings.py. Ele é um módulo normal do Python com variáveis representando as configurações do Django. Altere essas configurações para que atendam aos parâmetros de conexão do seu banco de dados:
- DATABASE_ENGINE -- Um entre 'postgresql_psycopg2', 'mysql' ou 'sqlite3'. Outros backends também estão disponíveis.
- DATABASE_NAME -- O nome do seu banco de dados, ou o caminho completo (absoluto) para o arquivo do banco de dados se você estiver usando SQLite.
- DATABASE_USER -- Usuário do seu banco de dados (não utilizado para o SQLite).
- DATABASE_PASSWORD -- Senha do seu banco de dados (não utilizado para o SQLite).
- DATABASE_HOST -- O host onde seu banco de dados está. Deixe isso em branco se o seu servidor de banco de dados está na mesma maquina física (não utilizado para o SQLite).
Nota
Se você estiver usando PostgreSQL ou MySQL, certifique-se de que já tenha criado o banco de dados a partir desse ponto. Faça isso com "CREATE DATABASE database_name;" a partir do prompt interativo do seu banco de dados.
Enquanto você estiver editando o settings.py, note a configuração do INSTALLED_APPS próximo ao final do arquivo. Aquela variável possui os nomes de todas as aplicações Django que estiverem ativadas 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 de outros em seus projetos.
Por padrão, o INSTALLED_APPS contém as seguintes aplicações, que vem com o Django:
- django.contrib.auth -- Um sistema de autenticação.
- django.contrib.contenttypes -- Um framework para tipos de conteúdo.
- django.contrib.sessions -- Um framework de sessão.
- django.contrib.sites -- Um framework para gerenciamento de múltiplos sites com uma instalação do Django.
Essas aplicações são incluídas por padrão como uma conveniência para os casos comuns.
Cada uma dessas aplicações faz 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 usá-las, para isso rode o seguinte comando:
python manage.py syncdb
O comando syncdb verifica a configuração do INSTALLED_APPS e cria todas as tabelas necessárias de acordo com a configuração do banco de dados no seu arquivo settings.py. Você irá ver uma mensagem para cada tabela do banco de dados que ele criar, e você irá receber um prompt perguntandose a você se você gostaria de criar uma conta de super-usuário para o sistema de autenticação. Vá em frente e faça isso.
Se você estiver interessado, rode o cliente de linha de comando do seu banco de dados e digite \dt (PostgreSQL), SHOW TABLES; (MySQL), ou .schema (SQLite) para mostrar as tabelas que o Django criou.
Para os detalhistas
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) apropriadas do INSTALLED_APPS antes de rodar o syncdb. O comando syncdb irá criar apenas as tabelas para as aplicações que estiverem no INSTALLED_APPS.
Agora que seu ambiente -- um "projeto" -- está configurado, você está pronto para começar o trabalho.
Cada aplicação que você escreve no Django consiste de um pacote Python, em algum lugar no seu caminho do Python, que seguirá uma certa convenção. O Django vem com um utilitário que gera automáticamente a estrutura básica de diretório de uma aplicação, então você pode se concentrar apenas em escrever código ao invés de ficar criando diretórios.
Projetos vs. aplicações
Qual é a diferença entre um projeto e uma aplicação? Uma aplicação é uma aplicação Web que faz alguma coisa -- ex.: um sistema de blog, um banco de dados de registros públicos ou uma simples aplicação de enquete. Um projeto é uma coleção de configurações e aplicações para um determinado Web site. Um projeto pode conter múltiplas aplicações. Uma aplicação pode estar em múltiplos projetos.
Nesse tutorial nós iremos criar nossa aplicação de enquete no diretório mysite, para simplificar. Como Conseqüência, a aplicação irá ser acoplada ao projeto -- assim sendo, o código Python interno da aplicação da enquete irá se referir a mysite.polls. Posteriormente, nesse tutorial, nós iremos discutir como desacoplar suas aplicações para distribuição.
Para criar sua aplicação, certifique-se de que você está no diretório mysite e digite esse comando:
python manage.py startapp polls
Isso irá criar um diretório polls, que irá ser apresentado desta forma:
polls/
__init__.py
models.py
views.py
Essa estrutura de diretório irá abrigar a aplicação de enquete.
O primeiro passo ao escrever uma aplicação Web de banco de dados no Django é definir seus modelos -- essencialmente, o layout do seu banco de dados, com metadados adicionais.
Filosofia
Um modelo é a única e definitiva fonte de dados sobre seus dados. Ele contém os campos essenciais e o comportamentos para os dados que você estiver armazenando. O Django segue o princípio DRY. O objetivo é definir seu modelo de dados em um local e automáticamente derivar coisas a partir dele.
Na nossa aplicação simples de enquete, nós iremos criar dois modelos: polls e choices. Uma enquete (poll) tem uma pergunta e uma data de publicação. Uma escolha (choice) tem dois campos: o texto da escolha e um totalizador de votos. Cada escolha é associada a uma enquete.
Esses conceitos são representados por simples classes Python. Edite o arquivo polls/models.py e ele se parecerá com isso:
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
Erros sobre max_length
Se o Django retornar para você uma mensagem de erro dizendo que o max_length não é um argumento válido, você provávelmente está usando uma versão antiga do Django. (Essa versão do tutorial foi escrita para a última versão de desenvolvimento do Django.) Se você estiver usando um checkout de Subversion da versão de desenvolvimento do Django (veja a documentação de instalação para mais informações), você não deveria ter nenhum problema.
Se você quiser continuar com uma versão antiga do Django, você deverá mudar para o tutorial do Django 0.96, porque este tutorial cobre vários recursos que só existem na versão de desenvolvimento do Django.
O código é auto-explicativo. Cada modelo é representado por uma classe derivada da classe django.db.models.Model. Cada modelo tem um número de variáveis de classe, as quais por sua vez representam um campo de banco de dados no modelo.
Cada campo é representado por uma instância de uma classe models.*Field -- ex.: models.CharField para campos do tipo caractere e models.DateTimeField para datetimes. Isso diz ao Django qual tipo de dados cada campo suporta.
O nome de cada instância models.*Field (ex.: question ou pub_date ) é o nome do campo, em formato amigável para a maquina. Você irá usar esse valor no seu código Python, e seu banco de dados irá usá-lo como nome de coluna.
Você pode usar um argumento na primeira posição de um Field para designar um nome legível para humanos. O qual será usado em uma série de partes introspectivas do Django, e ele também servirá como documentação. Se esse campo não for fornecido, o Django irá usar o nome legível para a máquina. Nesse exemplo nós definimo um nome legível para humanos apenas para Poll.pub_date. Para todos os outros campos nesse modelo o nome legível para a maquina servirá como nome legível para humanos.
Algumas classes Field possuem elementos obrigatórios. O CharField, por exemplo, requer que você informe a ele um max_length. Isso é usando não apenas no esquema do banco de dados, mas na validação, como nós veremos em breve.
Finalmente, note a definição de um relacionamento, usando models.ForeignKey. Que diz ao Django que cada Choice (Escolha) está relacionada a uma única Poll (Enquete). O Django suporta todos os relacionamentos de banco de dados comuns: muitos-para-um, muitos-para-muitos e um-para-um.
Aquela pequena parte do modelo fornece ao Django muita informação. Com ela o Django é capaz de:
- Criar um esquema de banco de dados (instruções CREATE TABLE) para essa aplicação.
- Criar uma API de acesso a banco de dados para acessar objetos Poll e Choice.
Mais primeiro nós precisamos dizer o 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 tem que ser atreladas a uma determinada instalação do Django.
Edite o arquivo settings.py novamente, e altere a configuração INSTALLED_APPS para incluir a string 'mysite.polls'. Então ela irá parecer com isso:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'mysite.polls'
)
Agora o Django sabe que o mysite inclui a aplicação polls. Vamos rodar outro comando:
python manage.py sql polls
Você deverá ver algo similar ao seguinte (as instruções SQL CREATE TABLE para a aplicação pools):
BEGIN;
CREATE TABLE "polls_poll" (
"id" serial NOT NULL PRIMARY KEY,
"question" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
"choice" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
COMMIT;
Note o seguinte:
- A saída exata irá variar dependendo do banco de dados que você está usando.
- Os nomes das tabelas são gerados automáticamente combinando o nome da aplicação (polls) e o nome em minúsculas do modelo -- poll e choice. (Você pode alterar esse comportamento.)
- Chaves primárias (IDs) são adicionadas automáticamente. (Você pode modificar isso, também.)
- Por convenção, o Django adiciona "_id" ao nome do campo chave estrangeira. Sim, você pode alterar isso, como quiser.
- O relacionamento da chave estrangeira é feito explicitamente por um instrução REFERENCES.
- Isso é 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ê automáticamente. O mesmo ocorre com as aspas dos nomes de campos -- ex.: usando aspas duplas ou aspas simples. O autor desse tutorial rodava PostgreSQL, então o saída do exemplo está na sintaxe do PostgreSQL.
- O comando sql atualmente não roda o SQL no seu banco de dados - ele apenas mostra-o na tela para que você possa ver o qual SQL o Django acha que seja necessário. Se você quiser, você pode copiar e colar esse SQL no prompt do seu banco de dados. Entretanto, como nós iremos ver em breve, o Django fornece uma maneira mais fácil de submeter o SQL ao banco de dados.
Olhar para a saída desses comandos irá ajudar a entender o que está acontecendo por baixo do pano.
Agora, rode o syncdb novamente para criar essas tabelas de modelos no seu banco de dados:
python manage.py syncdb
O comando syncdb roda o sql do 'sqlall' em seu banco de dados para todas as aplicações presentes no INSTALLED_APPS que ainda não existam em seu banco de dados. Isso criará todas as tabelas, dados iniciais e índices para quaisquer aplicações que você tenha adicionado ao seu projeto desde a última vez que você rodou o syncdb. O syncdb pode ser chamado sempre que você quiser, e ele irá apenas criar as tabelas que não existirem.
Leia a documentação do django-admin.py para informações completas sobre o que o utilitário manage.py pode fazer.
Agora, vamos dar uma passada no shell interativo do Python e brincar um pouco com a API grátis que o Django dá a você. Para invocar o shell do Python, use esse comando:
python manage.py shell
Nós usaremos isso ao invés de simplesmente digitar "python", porque o manage.py configura o ambiente de projeto para você. "A configuração do ambiente" envolve duas coisas:
Colocar o mysite no sys.path. Buscando flexibilidade, várias partes do Django referem-se aos projetos usando a notação pontuada do Python (ex.: 'mysite.polls.models'). Para que isso funcione, o pacote mysite precisa estar no sys.path.
Nós já vimos um exemplo disso: a configuração INSTALLED_APPS é uma lista de pacotes na notação pontuada de caminho.
Configurar a variável de ambiente DJANGO_SETTINGS_MODULE, que fornece ao Django o caminho para o seu arquivo settings.py.
Ignorando o manage.py
Se você optar por não usar o manage.py, não há problemas. Apenas certifique-se de que o mysite está no nível raíz do caminho do Python (ex.: import mysite funciona) e configure a variável de ambiente DJANGO_SETTINGS_MODULE para mysite.settings.
Para mais informações sobre tudo isso, veja a documentação do django-admin.py.
Assim que você estiver no shell, explore a API de banco de dados:
# Importe as classes modelo que acabamos de criar. >>> from mysite.polls.models import Poll, Choice # Não há nenhuma enquete no sistema ainda. >>> Poll.objects.all() [] # Crie uma nova Poll (enquete). >>> import datetime >>> p = Poll(question="What's up?", pub_date=datetime.datetime.now()) # Salve o objeto na base de dados. Você tem que chamar o save() explicitamente. >>> p.save() # Agora ela tem uma ID. Note que ele irá mostrar "1L" ao invés de "1", # dependendo de qual banco de dados você está usando. Não é nada demais; isso # apenas significa que o backend do seu banco de dados prefere retornar # inteiros como objetos inteiros longos do Python. >>> p.id 1 # Acesse colunas do banco de dados via atributos do Python. >>> p.question "What's up?" >>> p.pub_date datetime.datetime(2007, 7, 15, 12, 00, 53) # Modifique valores alterando os atributos e depois chamando o save(). >>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0) >>> p.save() # objects.all() mostra todas as enquetes do banco de dados. >>> Poll.objects.all() [<Poll: Poll object>]
Espere um pouco. <Poll: Poll object> é, uma representação totalmente inútil desse objeto. Vamos corrigir isso editando o modelo de enquetes (no arquivo polls/models.py) e adicionando um método __unicode__() a ambos Poll e Choice:
class Poll(models.Model):
# ...
def __unicode__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
return self.choice
Se o __unicode__() parecer não funcionar
Se você adicionar o método __unicode__() aos seus modelos e não ver nenhuma mudança na forma com que eles são representados, você deve estar usando uma versão antiga do Django. (Essa versão do tutorial foi escrita para a última versão de desenvolvimento do Django.) Se você estiver usando um checkout do Subversion do Django (veja a documentação de instalação para mais informações), você não deveria estar tendo nenhum problema.
Se você quiser seguir com uma versão antiga do Django, você deverá mudar para o tutorial do Django 0.96, porque esse tutorial cobre vários recursos que existem apenas na versão de desenvolvimento do Django.
É importante adicionar métodos __unicode__() aos seus modelos, não apenas para sua própria sanidade quando estiver lidando com o prompt interativo, mas também porque representações de objetos são usadas em toda administração gerada automáticamente pelo Django.
Por que __unicode__() e não __str__()?
Se você é familiarizado com o Python, você deve ter o hábito de adicionar métodos __str__() às suas classes, não métodos __unicode__(). Nós usamos __unicode__() aqui porque os modelos do Django lidam com Unicode por padrão. Todos os dados armazenados nos seus bancos de dados são convertidos para Unicode quando são retornados.
Os modelos do Django tem um método padrão __str__() que chama o __unicode__() e converte os resultados para uma bytestring UTF-8. Isso significa que unicode(p) irá retornar uma string Unicode, e que str(p) irá retornar uma string normal, com caracteres codificados como UTF-8.
Se tudo isso é grego para você, apenas lembre-se de adicionar métodos __unicode__() aos seus modelos. Com alguma sorte, as coisas deverão Simplesmente Funcionar para você.
Note que esses são métodos Python normais. Vamos adicionar um método personalizado, apenas por demonstração:
import datetime
# ...
class Poll(models.Model):
# ...
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
Note a adição de import datetime para referenciar o módulo padrão do Python datetime.
Vamos voltar um pouco ao shell interativo do Python rodando python manage.py shell novamente:
>>> from mysite.polls.models import Poll, Choice
# Certifique-se de que a sua adição do __unicode__() funcionou.
>>> Poll.objects.all()
[<Poll: What's up?>]
# O Django fornece uma rica API de procura em banco de dados inteiramente
# controlada por argumentos formados por palavras-chave.
>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]
# Pegue a enquete cujo ano é 2007. Claro que, se você estiver seguindo esse
# tutorial em outro ano, mude como for apropriado.
>>> Poll.objects.get(pub_date__year=2007)
<Poll: What's up?>
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Poll matching query does not exist.
# Buscar por uma chave primária é o caso mais comum, então o Django fornece um
# atalho para buscas por chaves primárias específicas.
# O que se segue é idêntido a Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What's up?>
# Certifique-se de que o método personalizado funcionou.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_today()
False
# Dê à enquete (``Poll``) algumas opções (``Choices``). A chamada ``create`` constrói um
# novo objeto opção (``choice``), executa a instrução INSERT, adiciona a escolha ao
# conjunto de escolhas disponíveis e retorna o novo objeto opção (``Choice``).
>>> p = Poll.objects.get(pk=1)
>>> p.choice_set.create(choice='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice='Just hacking again', votes=0)
# Objetos ``Choice`` possuem acesso via API aos seus objetos ``Poll`` relacionados.
>>> c.poll
<Poll: What's up?>
# E vice-versa: Objetos ``Poll`` possuem acesso aos objetos ``Choice``.
>>> p.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3
# A API segue automáticamente os relacionamentos da forma como você precisa.
# Use ``underscores`` duplos para separar relacionamentos.
# Isso funciona em tantos níveis abaixo quando você quiser; não há limite.
# Encontre todas as opções (``choices``) para uma enquete cuja ``pub_date`` é em 2007.
>>> Choice.objects.filter(poll__pub_date__year=2007)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
# Vamos deletar uma das escolhas. Use delete() para isso.
>>> c = p.choice_set.filter(choice__startswith='Just hacking')
>>> c.delete()
Para um detalhamento completo da API de banco de dados, veja nossa referência à API de Banco de Dados.
Quando você se sentir confortável com a API, leia a parte 2 desse tutorial para colocar a administração automática do Django para funcionar.
Hospedado por PyTown.com. Django Brasil é a comunidade brasileira de usuários do framework web Django. Django é uma marca registrada de Lawrence Journal-World.