Back-End

11 jul, 2013

O “objeto” admin de um app

Publicidade

Após um longo tempo sem escrever, retorno com a continuação da série sobre os objetos de uma aplicação no Django. Hoje irei tratar sobre o admin, que é considerado por muitos como a grande vantagem do Django em relação aos demais frameworks – tanto em Python como em outros frameworks de outras linguagens.

Eu acho esse tipo de pensamento muito restrito, pois o Django é muito mais que o admin. Concordo plenamente que a utilização do admin reduz absurdamente o tempo de desenvolvimento de qualquer tipo de aplicação, mesmo quando se torna necessário realizar algum tipo de customização da interface. Um simples exemplo que posso citar é o campo do tipo Date, onde precisamos trabalhar com arquivos JS para criarmos uma boa experiência para o usuário. No Django, esse elemento já é configurado por padrão; sem necessidade de intervenção nossa em nenhum outro arquivo.

O admin se utiliza das configurações realizadas no objeto models.py para realizar a “mágica” de com apenas uma linha, registrar o admin, criar a interface para o usuário final. Vamos então mostrar um simples exemplo aqui de como podemos, com apenas uma linha, “gerar” o front-end do cliente. Tendo uma app já criada, vamos fazer dois passos:

  1. Criar um arquivo admin.py no diretório da nossa app;
  2. Editar o arquivo admin.py criado e registrar o admin para nosso model.

Para entendermos melhor, vamos utilizar como modelo o model a seguir:

class Contato(models.Model):
 nome = models.CharField(max_length=150, verbose_name=u'Nome')
 empresa = models.CharField(max_length=150, verbose_name=u'Empresa',
 null=True, blank=True)
 email = models.EmailField(verbose_name=u'E-mail')
 telefone = models.CharField(max_length=255, verbose_name=u'Telefone',
 default='0')
 mensagem = models.TextField(verbose_name=u'Mensagem')
 cidade = models.CharField(max_length=250)
 estado = models.CharField(max_length=250)
 assunto = models.CharField(verbose_name=u'Assunto do contato', max_length=250)
 tipo_contato = models.ForeignKey(TipoContatoCliente,
 verbose_name=u'Tipo do contato')
 processado = models.BooleanField(u'Contato respondido?', default=False)
 acao_tomada = models.TextField(verbose_name=u'Ação de resposta ao contato',
 null=True, blank=True)
 atendente = models.ForeignKey(Equipe, verbose_name='Atendente', null=True,
 blank=True)
 data_recebimento = models.DateField(u'Data de recebimento', null=True,
 blank=True, auto_now_add=True)
 data_resposta = models.DateField(u'Data de resposta', auto_now=True,
 null=True, blank=True)
 fkSetor = models.ForeignKey(SetorFuncionario, verbose_name='Empresa',
 null=True, blank=True)
 fkEmpresa = models.ForeignKey(Empresa, verbose_name='Site/Empresa', null=True, blank=True)

 def __unicode__(self):
 return unicode(self.nome)

Não irei me ater aos detalhes da nossa Classe (model), pois o foco aqui é o objeto admin. Para que a “mágica” aconteça, vamos editar nosso arquivo admin.py deixando ele assim:

from django.contrib import admin
from contatos.models import Contato

admin.site.register(Contato)

Tudo bem, eu falei que seria apenas uma linha e escrevemos três, mas vamos pensar: na linha 1 fizemos a importação do admin do Django; na segunda, importamos a Classe do nosso model que iremos registrar e na 3ª é que realmente registramos nosso admin, mas independente de ser 1 ou 3 linhas o resultado é esse:

Captura-de-Tela-40-e1369573922691
Change List do Admin
Captura-de-Tela-42-e1369574224791
Add Form
Captura-de-Tela-43-e1369575166488
Change form

Vejam que com um simples registro temos as interfaces (telas) necessárias para que o usuário do sistema possa gerenciar as informações. Agora tenho que destacar que o front-end gerado no exemplo não é o padrão Admin do Django. Essa é uma customização que fiz nos templates do Admin, essa interface está disponível no meu GitHub é opensource e podem utilizar o quanto desejarem – contribuam também com melhorias.

Achou fantástico? Calma, ainda temos um longo caminho, pois o admin tem muita coisa (como falei antes, podemos modificar o admin da maneira que precisarmos/desejarmos). Vamos agora para algumas coisas mais legais ainda!

Para que possamos modificar a configuração padrão do admin deveremos criar uma classe dentro do admin.py, ficando assim nossa classe.

class ContatoAdmin(admin.ModelAdmin):

 class Media:
 js = ("tinymce/jscripts/tiny_mce/tiny_mce.js",
 "tinymce/jscripts/tiny_mce/textarea.js",
 )

 search_fields = ('tipo_contato', 'nome', 'empresa', 'email', 'telefone')
 list_per_page = 10
 save_on_top = True
 fieldsets = [
 (None, {'fields': ['tipo_contato',
 'nome', 'empresa',
 ('email', 'telefone'),
 'mensagem',
 ('processado', 'acao_tomada'), ]}),
 ]

admin.site.register(Contato, ContatoAdmin)

Vamos para as explicações necessárias:

  • Linha 1: Criando a Classe ContatoAdmin, por padrão, eu sempre trabalho com NomeModel e o sulfixo Admin, assim fica fácil de entender.  A nossa classe é do tipo admin.ModelAdmin, pois vamos de certa forma subscrever o objeto admin.ModelAdmin da classe em questão;
  • Linha 3: Aqui configuramos os arquivos js para que os elementos do tipo TextArea recebam o editor TinyMCE;
  • Linha 8: Outra “mágica”, com essa configuração eu determino quais campos do Model poderão ser utilizados para realizar pesquisas, quando o usuário estiver na tela de listagem (change_list);
  • Linha 9: Aqui estou simplesmente determinando quantos elementos o admin deve mostrar por página, percebam aqui que é muito simples fazer a customização que desejamos;
  • Linha 10: Novamente, de forma bem sugestiva, configuro para que a barra de save seja mostrada também no topo do formulário (change_form);
  • Linha 12: Já o fieldsets serve para quando desejamos reordenar os atributos, que serão transformados em campos de formulário;

Agora vejamos o que temos depois dessas configurações, comparando claro com os outros print’s já mostrados acima:

Nova change list
Nova change list

Aqui podemos verificar que muita coisa mudou. Temos um campo de pesquisa, resultado da configuração do search_fields e também podemos verificar a numeração no canto direito inferior, sendo esse resultado da configuração list_per_page.

Captura-de-Tela-45-e1369593961955
Novo formulário

Já o formulário ficou dessa forma. Comparando com o mostrado acima, podemos ver que os campos estão numa disposição diferente e ainda temos um editor WYSIWYG, o que possibilita a inserção de texto formatado. No template temos que utilizar uma TemplateTag, mas depois falaremos disso.

Para não me estender muito, deixarei para depois outras configurações mais avançadas, como por exemplo mostrar no change_list apenas os elementos pertencentes ao usuário logado. No nosso caso, como estamos trabalhando com itens de contato, iremos limitar os contatos enviados para o usuário logado.

Também iremos subscrever os itens mostrados num ComboBox, trazendo apenas elementos que o usuário logado pode visualizar.