HERSONLS django, python e web
Django admin: Como criar views para admin
Neste artigo vamos criar uma nova funcionalidade na administração do django através da adição de views na aplicação admin do Django.
Levando em conta que possuímos uma aplicação chamada questao, vamos adicionar uma views onde irá mostrar uma lista com as questões respondidas.
Segue o models.py:
from django.db import models
class Questao(models.Model):
pergunta = models.CharField(max_length=255)
resposta = models.TextField(blank=True)
def __unicode__(self):
return unicode(self.pergunta)
Com o modelo pronto podemos partir para parte da administração. Tudo é bem simples e funciona da forma que costumamos criar associações comuns entre padrões de URL e definições de views. Vamos ao admin.py:
from django import template
from django.contrib import admin
from django.conf.urls.defaults import *
from django.shortcuts import render_to_response
from models import Questao
class QuestaoAdmin(admin.ModelAdmin):
def questoes_respondidas(self, request):
objetos = self.model.objects.exclude(resposta='')
app_label = self.model._meta.app_label
return render_to_response('admin/%s/questaorespondida_list.html' % app_label,
{'objetos': objetos},
context_instance=template.RequestContext(request))
def get_urls(self):
urls = super(QuestaoAdmin, self).get_urls()
minhas_urls = patterns('',
(r'^questoes-respondidas/$', self.questoes_respondidas)
)
return minhas_urls + urls
admin.site.register(Questao, QuestaoAdmin)
Analisando o código podemos ver que temos duas definições de função no ModelAdmin QuestaoAdmin. A definição de get_urls retorna para o sistema de administração todas os padrões de urls disponíveis para a mesma, nela fizemos uma chamada dela mesma e associamos o seu resultado para a variável urls, com isso temos todas as as urls padrões da administração. Logo criamos o padrão de url para utilizarmos com a views que irá mostrar a lista de questões respondidas ( note que nela ao invés de adicionarmos o caminho para a função, utilizamos self pois a views esta contida na classe ). Feito o padrão de url retornamos a adição da nova url com as urls padrões, fazendo com que nossa url fique disponível para administração.
Tendo criado a url e apontado para a views estará tudo meio caminho andado. Agora vamos entender a views. A definição views é bastante familiar porem com apenas um parâmetro a mais que é o self. Logo na linha seguinte fazemos a queryset utilizando a instância criada pelo ModelAdmin em self.model, excluindo todos os linhas que não possuem resposta. Nas linhas seguintes utilizamos o render_to_response para renderizar o template juntamente com a queryset passada como contexto, podemos ver que para gerar o nome do template, foi feito de maneira dinâmica onde pegamos o nome da aplicação e utilizamos para especificar o diretório do template, isso é muito util quando você necessita criar uma funcionalidade genérica, onde a classe que a herdou possa ser utilizada por ela, mas nesse caso foi utilizado apenas por convenção minha. Lembrando que esta views é publica e não possui nenhuma restrição para acessos, sugiro que leia sobre permissões[1] antes de criar views para demonstração ( breve falarei sobre o assunto ).
Com tudo isto feito basta criar o template questaorespondida_list.html dentro do diretório de templates, que no nosso caso, ficara contido dentro de 'admin/questao/' ficando desta forma "templates/admin/questao/questaorespondida_list.html". Se no caso você optar por colocar seus templates juntamente com o diretório da aplicação, desta forma irá ser satisfatória, mas caso deseje colocar dentro de algum diretório de templates especificado no arquivo settings basta ignorar o primeiro diretório do exemplo ("admin/questao/questaorespondida_list.html"). Segue um pequeno html de exemplo:
<h1>Questões respondidas</h1>
<ul>
{% for obj in objetos %}
<li>
<h2>{{ obj.pergunta }}</h2>
{{ obj.resposta }}
</li>
{% endfor %}
</ul>
<p><a href="{% url admin:questao_questao_changelist %}">Voltar</a></p>
O exemplo de template é bem simples e pode ser melhor aproveitado de diversas formas e uma das mais comuns é estendendo os templates disponíveis da administração[2] mais um assunto para outro artigo.
Bem simples não? mas precisamos de algo para acessar esta pagina em nossa interface administrativa. Para isto faremos uma pequena alteração no template change_list.html para a aplicação questao. Faça uma copia do template change_list.html contido em 'django/contrib/admin/templates/admin/' para o mesmo diretório do template que criamos mais cedo e adicione as seguintes linhas dentro da lista '<ul class="object-tools">':
<li>
<a href="questoes-respondidas/" class="addlink">
Visualizar questões respondidas
</a>
</li>
Pronto, agora já foi solucionado o problema de acessibilidade. Acesse a administração e adicione algumas questões, tanto com resposta quanto sem e visualize a nova views da adminstração.
Faça o download do projeto exemplo: djadminviews.tar.bz2
6Comentarios
-
Diego Henrique Oliveira
- 24/02/2010
Justamente o que eu estava procura. Isso me será muito util.
Parabens pelo blog.
Abraços -
Fernando Freitas Alves
- 24/02/2010
Muito bo seu artigo!
Eu só acho que a fonte da sua página está um pouco difícil de ler. Mas copiei e colei em outro lugar
Vlw
FFA -
Igor Sobreira
- 24/02/2010
Bom artigo!
Só faltou um detalhe na sua view: permissão. Como ela está no admin, deve ter as mesmas permissões. No ModelAdmin dá pra fazer assim.
(r'^questoes-respondidas/$', self.admin_site.admin_view(self.questoes_respondidas))
o método admin_view() do AdminSite verifica as permissões, é ele que o admin usa nas views internas.
Abraço -
hersonls
- 24/02/2010
@IgorSobreira muito obrigado pela ajuda e como você deve ter lido, mencionei sobre a questão da permissão e deixei isto a par do desenvolvedor porque acredito que para cada tipo de aplicação conta os tipos de permissões que podem variar dependendo de sua necessidade. -
tiago moraes
- 03/03/2010
Parabéns pelo documento, acredito que isso me ajudar muito, Colocando ele pra funcionar ocorreu isso e não achei o problema:
Debian
django 1.0.2
python 2.4.6
invalid literal for int() with base 10: 'questoes-respondidas'
Sabe porque disso? -
diofeher
- 11/03/2010
Muito bom o artigo!
