Django Brasil


Documentação em português


Escrevendo sua primeira aplicação Django, parte 2

Este tutorial inicia-se onde o Tutorial 1 terminou. Vamos continuar a aplicação web de enquete focando agora no site de administração automática do Django.

Filosofia

Gerar sites de administração para sua equipe ou clientes adicionarem, editarem ou excluírem conteúdo é um trabalho entediante que não requer muita criatividade. Por essa razão, o Django automatiza toda a criação da interfaces de administração para os modelos.

O Django foi inicialmente desenvolvido em um ambiente de jornal, 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.

Ative o site de admin

O site de administração não vem ativo por padrão -- ele é opcional. Para ativá-lo para sua instalação, siga estes três passos:

  • Adicione "django.contrib.admin" às suas configurações de "INSTALLED_APPS".

  • Execute python manage.py syncdb. Já que uma nova aplicação foi adicionada ao INSTALLED_APPS, as tabelas do banco de dados precisam ser atualizadas.

  • Edite seu arquivo meusite/urls.py e retire o comentário das linhas abaixo de "Uncomment this for admin:". Esse arquivo é um URLconf; entraremos em detalhes sobre URLconfs no próximo tutorial. Por enquanto, tudo o que você tem a saber é que ele mapeia as URL principais para as aplicações. No final você deve ter um urls.py parecido com este:

    from django.conf.urls.defaults import *
    
    # Uncomment the next two lines to enable the admin:
    from django.contrib import admin
    admin.autodiscover()
    
    urlpatterns = patterns('',
        # Example:
        # (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
    
        # Uncomment the next line to enable admin documentation:
        # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    
        # Uncomment the next line for to enable the admin:
        (r'^admin/(.*)', admin.site.root),
    )
    

    (As linhas em negrito são as que precisam ser descomentadas.)

Inicie o servidor de desenvolvimento

Vamos iniciar o servidor de desenvolvimento e explorar o site admin.

Lembre-se do Tutorial 1 onde você iniciou o servidor com:

python manage.py runserver

Agora, abra o navegador de internet e vá para "/admin/" no seu domínio local -- por exemplo, http://127.0.0.1:8000/admin/. Você deverá ver a tela de login:

Tela de login do Django admin

Entre no site de administração

Agora tente acessar o sistema. (Você criou uma conta de superusuário na primeira parte deste tutorial, lembra?). Você deverá ver a página inicial do Django admin:

Página inicial do Django admin

Você deverá ver alguns outros tipos de conteúdos editáveis, incluindo grupos, usuários e sites. Essas são as funcionalidades centrais que o Django inclui por padrão.

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

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

Somente uma coisa precisa ser feita: temos que especificar no modelo "Poll" que os objetos "Poll" possuem uma interface de administração. Edite o arquivo "meusite/enquete/models.py" e adicione o seguinte ao final do arquivo:

from django.contrib import admin

admin.site.register(Poll)

Agora atualize a página do Django admin para visualizar as alterações. Observe que você não tem que reiniciar o servidor de desenvolvimento -- ele recarregará seu projeto de modo que todas as modificações no código serão vistas imediatamente no seu navegador.

Explore a funcionalidade de administração gratuita

Agora que nós registramos Poll, o Django sabe que ele deve ser exibida na página principal do admin:

Página principal de administração, agora com enquetes exibidas

Clique em "Polls". Agora você está na página "lista de alteração" para as enquetes. Essa página exibe todas as enquetes no banco de dados e permite ao usuário alterá-las. Existe a enquete "What's up?" criada no primeiro tutorial:

Lista de alteração de enquetes

Clique na enquete "What's up?" para editá-la:

Formulário de edição para a enquete

Note o seguinte:

  • O formulário é gerado automaticamente a partir do modelo Poll.
  • Os diferentes tipos de campos do modelo (models.DateTimeField, models.CharField) correspondem aos respectivos widgets HTML de inserção. Cada tipo de campo sabe como exibir a si mesmo no Django admin.
  • Cada DateTimeField ganha um atalho JavaScript gratuito. Datas têm um atalho "Today" e um calendário popup, e horas têm um atalho "Now" e um conveniente popup com listas de horas comumente usadas.

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

  • Save -- Salva as alterações e retorna à lista para edição deste tipo de objeto.
  • Save and continue editing -- Salva as alterações e retorna à página deste objeto.
  • Save and add another -- Salva as informações e abre um formulário em branco deste tipo de objeto.
  • Delete -- Exibe uma página de confirmação de exclusão.

Altere a "Publication date" clicando nos atalhos "Today" e "Now". Em seguida, clique em "Save and continue editing." Então clique em "History" no canto superior direito. Você verá uma página exibindo todas as alterações feitas ao objeto pelo Django admin, com a hora e o nome de usuário da pessoa que fez a alteração:

Página de histórico para o objeto Poll.

Personalize o formulário de Administração

Tire alguns minutos para apreciar todo o código que você não teve que escrever. Quando você chama admin.site.register(Poll), o Django simplesmente permite que você edite o objeto e "adivinha" como exibi-lo dentro do admin. Com freqüência, você desejará controlar como o admin se parece e trabalha. Você fará isso informando ao Django sobre as opções que você quer quando registra o objeto.

Vamos ver como isso funciona reordenando os campos no formulário de edição. Substitua a linha admin.site.register(Poll) por:

class PollAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question']

admin.site.register(Poll, PollAdmin)

Você seguirá este padrão -- criar um objeto de modelagem do admin e então passá-lo como segundo argumento para o admin.site.register() -- sempre que precisar alterar as opções de admin para um objeto.

Essa mudança específica no código acima faz com que a "Publication date" seja mostrada em primeiro lugar, e não em segundo:

Os campos foram reordenados

Isso não é impressionante com apenas dois campos, mas para formulários com dúzias deles, escolher uma ordem intuitiva é um detalhe importante para a usabilidade.

E por falar em dúzias de campos, você pode querer dividir o formulário em grupos (fieldsets):

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Poll, PollAdmin)

O primeiro elemento de cada tupla em fieldsets é o título do grupo. Aqui está a aparência do nosso formulário agora:

O formulário possui grupos de campos agora

Você pode atribuir classes HTML arbitrárias para cada grupo. O Django fornece uma classe "collapse" que exibe um grupo particular inicialmente recolhido. Isso é útil quando você tem um formulário longo que contém um grupo de campos que não são comumente utilizados:

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
Grupo de campos (fieldset) inicialmente recolhido

Adicione objetos relacionados

OK, temos nossa página de administração de Enquetes. Mas uma Poll (enquete) tem múltiplos Choices (opções), e a página de administração não exibe as opções.

Ainda.

Há duas formas de solucionar esse problema. A primeira é registrar Choice no admin, assim como fizemos com Poll. Isto é fácil:

admin.site.register(Choice)

Agora "Choices" é uma opção disponível no Django admin. O formulário de "Add choice" se parece com isto:

Página de admin para Choice

Nesse formulário, o campo "Poll" é uma caixa de seleção contendo todas as enquetes no banco de dados. O Django sabe que uma ForeignKey (chave estrangeira) deve ser representada no admin como um campo <select>. No nosso caso, só existe uma enquete até agora.

Observe também o link "Add Another" (adicionar outra) ao lado de "Poll". Todo objeto com um relacionamento de chave estrangeira para outro ganha essa ação gratuitamente. Quando você clica em "Add Another", você terá uma janela popup com o formulário "Add poll". Se você adicionar uma enquete na janela e clicar em "Save", o Django salvará a enquete no banco de dados e irá dinamicamente adicionar a opção já selecionada ao formulário "Add choice" que você está vendo.

Mas, sério, essa é uma maneira ineficiente de adicionar objetos Choice ao sistema. Seria muito melhor se você pudesse adicionar várias opções diretamente quando criasse um objeto Poll (enquete). Vamos fazer isso acontecer.

Remova a chamada register() do modelo Choice. Então edite o código de registro de Poll para que fique assim:

class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Poll, PollAdmin)

Isso diz ao Django: "Objetos Choice são editados na mesma página de administração de Poll. Por padrão, forneça campos suficientes para 3 Choices."

Carregue a página "Add poll" para ver como está:

Página Add Poll contém Choices agora

Funciona assim: Há três blocos para Choices relacionados -- como especificado em extra --, mas a cada vez que você retorna à página de "Alteração" para um objeto já criado, você ganha outros três slots extras.

No entanto, há um pequeno problema. Um bocado de espaço na tela é tomado para exibir todos os três objetos Choice relacionados a serem inseridos. Por essa razão, o Django oferece uma maneira alternativa para exibir cada objeto relacionado em uma única linha; você só precisa alterar a declaração ChoiceInline para que leia:

class ChoiceInline(admin.TabularInline):
#...

Com o TabularInline (em vez de StackedInline), os objetos relacionados são exibidos de uma maneira mais compacta, baseada em tabela:

A página Add poll agora com opções compactas

Customize a página de lista de edição

Agora que a página de administração de Polls está bonita, vamos fazer algumas melhorias à página "change list" (lista de edição) -- aquela que exibe todas as enquetes do sistema.

Aqui como ela está até agora:

Página de lista de Enquetes

Por padrão, o Django mostra o str() de cada objeto. Mas algumas vezes seria mais útil se pudéssemos mostrar campos individuais. Para fazer isso, use a opção list_display, que é uma tupla de nomes de campos a serem exibidos, como colunas, na página de lista de edição dos objetos:

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question', 'pub_date')

Apenas para facilitar, vamos incluir o método customizado was_published_today do Tutorial 1:

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question', 'pub_date', 'was_published_today')

Agora a página de edição de enquetes está assim:

Página de edição de enquetes, atualizada

Você pode clicar no cabeçalho da coluna para ordená-las por estes valores -- exceto no caso do was_published_today, porque a ordenação pelo resultado de um método arbitrário não é suportada. Também note que o cabeçalho da coluna para was_published_today é, por padrão, o nome do método (com underscores substituídos por espaços). Mas você pode alterar isso fornecendo ao método um atributo short_description:

def was_published_today(self):
    return self.pub_date.date() == datetime.date.today()
was_published_today.short_description = 'Published today?'

Vamos adicionar uma outra melhoria à página de lista de edição: Filtros. Adicione a seguinte linha ao Poll.Admin:

list_filter = ['pub_date']

Isso adiciona uma barra lateral "Filter" que permite às pessoas filtrarem a lista de edição pelo campo pub_date:

Página de edição de enquetes, atualizada

O tipo de filtro exibido depende do tipo de campo que você está filtrando. Devido ao pub_date ser um DateTimeField, o Django sabe dar as opções de filtro para DateTimeFields: "Any date," "Today," "Past 7 days," "This month," "This year."

Isso está tomando uma boa forma. Vamos adicionar alguma capacidade de pesquisa:

search_fields = ['question']

Isso adiciona um campo de pesquisa ao topo da lista de edição. Quando alguém informa termos de pesquisa, o Django irá pesquisar o campo question. Você pode usar quantos campos quiser -- entretanto, porque ele usa um comando LIKE internamente, seja moderado para manter seu banco de dados feliz.

Finalmente, porque os objetos Poll possuem datas, é conveniente acompanhar por data. Adicione esta linha:

date_hierarchy = 'pub_date'

Isso adiciona uma navegação hierárquica, por data, no topo da página lista de edição. No nível mais acima, ele exibe todos os anos disponíveis. Então desce para os meses e, por último, os dias.

Agora é também uma boa hora para observar que a lista de edição fornece uma paginação gratuitamente. O padrão é mostrar 50 itens por página. A página da lista de edição, campos de pesquisa, filtros, hierarquia por data, ordenação por cabeçalho de coluna, todos trabalham em sincronia como deveriam.

Customize o look and feel do admin

Obviamente, ter "Django administration" no topo de cada página de admin é ridículo. Isso é só um texto de exemplo.

É fácil de editar, no entanto, usando o sistema de templates do Django. O Django admin é feito com o próprio Django e conseqüentemente sua interface usa o sistema de templates nativo do Django.

Abra seu arquivo de settings (mysite/settings.py, lembre-se) e veja a configuração TEMPLATE_DIRS. TEMPLATE_DIRS é uma tupla de diretórios de arquivos que serão verificados quando carregar os templates do Django, ou seja, caminhos de busca.

Por padrão, TEMPLATE_DIRS vem vazio. Portanto, vamos adicionar uma linha para dizer onde nossos templates Django estão:

TEMPLATE_DIRS = (
    "/home/my_username/mytemplates", # Altere isso para seu próprio diretório.
)

Agora copie o template admin/base_site.html de dentro do diretório padrão do Django admin (django/contrib/admin/templates) em um subdiretório admin onde quer que esteja o diretório que você está usando em TEMPLATE_DIRS. Por exemplo, se seu TEMPLATE_DIRS inclui "/home/my_username/mytemplates", como acima, então copie django/contrib/admin/templates/admin/base_site.html``para ``/home/my_username/mytemplates/admin/base_site.html. Não se esqueça do subdiretório admin.

Então simplesmente edite o arquivo e substitua o texto genérico do Django com o nome do seu próprio site como desejar.

Note que qualquer template padrão do admin pode ser sobrescrito. Para sobrescrever um template, apenas faça a mesma coisa que você fez com base_site.html -- copie ele do diretório padrão para o seu próprio diretório, e faça as mudanças.

Leitores astutos irão se perguntar: Mas se TEMPLATE_DIRS estava vazio por padrão, como o Django pôde encontrar o diretório padrão dos templates do admin? A resposta é, por padrão, o Django irá automaticamente procurar por um subdiretório templates/ dentro de cada pacote de aplicação, para usar como fallback. Veja a documentação de loader types - para a informação completa.

Customize a página inicial do admin

De maneira similar, você pode querer customizar o look and feel da página inicial do Django admin.

Por padrão, ela exibe todas as aplicações disponíveis, de acordo com sua configuração INSTALLED_APPS. Mas a ordem em que serão exibidas é aleatória, e você pode querer fazer alterações significativas no layout. Além do que, a página inicial é provavelmente a página mais importante no admin, e deve ser fácil de usar.

O template a ser customizado é o admin/index.html. (Faça o mesmo que foi feito com o admin/base_site.html na seção anterior -- copie ele do diretório padrão para o seu próprio diretório de templates). Edite o arquivo, e você verá que ele usa uma template tag chamada {% get_admin_app_list as app_list %}. Ela é a mágica que obtém todas as aplicações instaladas no Django. Em vez de usá-la, você pode explicitamente fazer os links para os objetos específicos na página de admin, da maneira que achar mais apropriado.

O Django oferece outro atalho neste departamento. Rode o comando python manage.py adminindex polls para pegar o trecho do código para a inclusão no template da página inicial do admin. É um ótimo ponto de partida.

Para um detalhamento completo na customização do look and feel do site do Django admin em geral, veja o Guia de CSS do Django admin.

Quando você se sentir confortável com o site de admin, leia a parte 3 deste tutorial para começar a trabalhar com as views públicas da enquete.


Hospedado por PyTown.com. Django Brasil é a comunidade brasileira de usuários do framework web Django. Django é uma marca registrada de Lawrence Journal-World.