Arquivo

Arquivo da Categoria ‘python’

Criando novas views para o admin

25, janeiro, 2010 Sem comentários

Um bom tempo sem postar nada novo… porém estou de volta com uma dica simples que já usei bastante.

Quem utiliza o Django com certeza adora a app admin que o acompanha, nós desenvolvedores ganhamos de presente uma administração de sites útil para praticamente qualquer site, e diga-se de passagem as administrações são sempre as partes mais chatas quando se produz um site.

Como nem tudo é perfeito, quando é necessário customizar o admin temos diversas opções, porém essa não é a intenção desse post. Quem quiser saber mais detalhes sobre customização do admin pode acessar a documentação do django e essa página da IBM.

O nosso caso é diferente, existem situações em que precisamos criar novas funcionalidades específicas para a administracao (não estão relacionadas a nenhum model), mantendo o layout e as restrições de acesso.

O primeiro passo é criar a view:

from django.shortcuts import render_to_response
from django.template import RequestContext

def minha_view(request):
    #executa alguma funcionalidade
    return render_to_response('app/minha_view.html',locals(),request_instance=RequestContext(request))

Note que a view acima é igual a qualquer outra que se faz normalmente.
Em seguida definimos uma url para nossa view:

urlpatterns = patterns('',
    (r'^admin/admin_view','app.views.minha_view'),
    (r'^admin/', include(admin.site.urls)),
)

Eu preciso definir a minha url antes da url do admin, se ela for colocada após o admin a view não é encontrada. Cuidado para não sobrepor nenhuma view já existente do admin.

Agora criamos o template minha_view.html:

{% extends 'admin/base_site.html' %}
{% block content %}
Aqui ficarão os dados da sua view
{% endblock %}

O template acima é muito simples, caso queira fazer algo mais sofisticado (como css, breadcrumbs e forms) sugiro olhar os templates padrões do admin. Eles podem ser encontrados em: %DJANGO_DIR%/contrib/admin/templates/admin.

Pronto, sua view já possui a ‘cara’ do admin. Porém ela pode ser acessada por qualquer usuário, até mesmo os logados.

O passo natural seria usar o decorator login_required para exigir o login, so que por algum motivo desconhecido os redirecionamentos do admin não combinam muito bem com views externas. Nesso caso a solução é transformar a nossa view numa view do admin, para isso editamos o urls.py:

from django.contrib import admin
from app.views import minha_view

urlpatterns = patterns('',
    (r'^admin/admin_view',admin.site.admin_view(minha_view),
    (r'^admin/', include(admin.site.urls)),
)

Pronto sua view está protegida de acessos anônimos e todos os redirecionamentos funcionam corretamente.
Agora é só criar suas novas funcionalidades embutidas diretamente no admin.

Espero ter ajudado. Até a próxima.

Categories: django, python Tags: , ,

Um pouco de metaprogramação

1, outubro, 2009 Sem comentários

Quem assina a lista django-brasil recebeu essa mensagem do Luciano Ramalho sobre metaprogramação. Achei muito interressante e demonstra perfeitamente o quão poderosa é a linguagem Python.

Estou reproduzindo o texto sem alterações:

Em geral não é tedioso programar com o Django, mas às vezes é, veja só quanta repetição:

# http://pastebin.com/f2fc7b238

class DescriptorInline(admin.TabularInline):
   model = Descriptor

class RecruitmentCountryInline(admin.TabularInline):
   model = RecruitmentCountry

class OutcomeInline(admin.StackedInline):

   model = Outcome

class TrialInterventionCodeInline(admin.TabularInline):

   model = TrialInterventionCode

class SecondaryNumberInline(admin.TabularInline):

   model = TrialNumber

class TrialContactInline(admin.TabularInline):

   model = TrialContact

class TrialInstitutionInline(admin.TabularInline):

   model = TrialInstitution

class ClinicalTrialAdmin(admin.ModelAdmin):

   inlines = [SecondaryNumberInline, RecruitmentCountryInline,

              OutcomeInline, TrialContactInline, TrialInstitutionInline,

              DescriptorInline, TrialInterventionCodeInline]

No código acima, cada nome de modelo aparece três vezes… (uma vez ao
declarar a classe XXXInline, no atributo model do inline, e mais uma
vez no atributo inlines).

Além disso, quase todas as declarações de inlines são idênticas… E o
princípio DRY, como fica?

Felizmente Django é Python. Então aquilo pode ser reescrito de uma
maneira mais legal assim:

# http://pastebin.com/f5af2bd28

tabular_inline_models = [Descriptor, RecruitmentCountry, TrialInterventionCode,

                        TrialNumber, TrialContact, TrialInstitution]

tabular_inlines = []

for model in tabular_inline_models:

   cls_name = model.__name__+'Inline'

   cls = type(cls_name, (admin.TabularInline,), {'model':model})

   tabular_inlines.append(cls)

class OutcomeInline(admin.StackedInline):

   model = Outcome

class ClinicalTrialAdmin(admin.ModelAdmin):

   inlines = tabular_inlines + [OutcomeInline]

O truque aqui foi usar a função type(), que pode ser usada para criar
classes dinamicamente. Para isso a gente passa três argumentos para a
função type():

- uma string que será o __name__ da classe
- uma tupla de super-classes (importante: a vírgula dentro do
parêntesis indica que é uma tupla de um elemento)
- um dicionário com os atributos da classe (métodos e variáveis)

Não tente fazer isso em Java ;-) .

[ ]s
Luciano

IV Encontro do GruPy-AL

1, agosto, 2009 Sem comentários

Para quem não sabe faço parte do GruPy-Al. Um grupo de desenvolvedores python do estado de Alagoas. Tudo bem que ainda não é uma participação muito ativa, mas pretendo mudar isso ai.

Quinta-feira aconteceu o IV Encontro, no auditório da IFAL (antigo CEFET), com a presença de 84 participantes, até agora o encontro com o maior número de participantes. Tudo bem que boa parte do pessoal eram alunos do IFAL, mas isso não vem ao caso.

Foram 3 palestras, uma sobre o wiki Moin Moin, uma sobre BRisa e outra sobre BRiGas.

Quem quiser saber mais detalhes sobre o grupo pode acessar a lista de discussão:

http://groups.google.com/group/grupy-al

Ou então acessar o blog:

http://grupyal.blogspot.com/

Categories: eventos, python Tags: ,