Mostrando postagens com marcador Django. Mostrar todas as postagens
Mostrando postagens com marcador Django. Mostrar todas as postagens

segunda-feira, 9 de abril de 2012

Django signals

Versão simplificada do método signal.connect do Django, mas ela insere o receiver como primeiro elemento da lista, ao contrário do comportamento padrão que insere no final. Para essa função funcionar sempre, ela deve ser chamada apenas uma vez por tipo de signal, então a use apenas em casos muito especiais.

Código:



def connect_as_first_signal(signal, receiver, sender=None, dispatch_uid=None):
"Similar to signal.connect(receiver, sender=sender), but put the receiver as the first element in the list."
from django.dispatch.dispatcher import _make_id
if dispatch_uid:
lookup_key = (dispatch_uid, _make_id(sender))
else:
lookup_key = (_make_id(receiver), _make_id(sender))
signal.lock.acquire()
try:
for r_key, _ in signal.receivers:
if r_key == lookup_key:
break
else:
signal.receivers.insert(0, (lookup_key, receiver))
finally:
signal.lock.release()


Uso:


from django.db.models.signals import pre_save
connect_as_first_signal(pre_save, SUA_FUNCAO_DE_CALL_BACK, sender=SEU_SENDER, dispatch_uid=SEU_ID)

sábado, 29 de outubro de 2011

Django: Quantidade de queries executada por teste

Django-Dynamic-Fixture 1.4.0 possui bugfixes e novas funcionalidades:

- Relatório com o número de queries executadas em cada método de teste: manage.py test --with-queries
- Conta quantas queries são executas ao inserir e atualizar um objeto (pode variar de acordo com listeners, sobrescrita do método save, etc): manage.py count_queries_on_save

http://code.google.com/p/django-dynamic-fixture/

quarta-feira, 12 de outubro de 2011

Apresentação sobre testes na Python Brasil 2011

Padrões de Testes Automatizados com Django

http://www.slideshare.net/paulocheque/padroes-de-testes-automatizados-com-django

domingo, 9 de outubro de 2011

Feature Flip para Continuous Deployment? Django Intruder

As ferramentas mais populares para ativar e desativar funcionalidades no Django são intrusivas, ou seja, é necessário acrescentar código adicional para permitir que uma funcionalidade seja ativada ou desativada. Essa abordagem é interessante, mas complexa para resolver um problema simples, além do que não é uma solução 100% dinâmica.

Django Intruder é uma solução simples e transparente para a aplicação. Sem qualquer código adicional é possível desativar qualquer request ao sistema.

http://code.google.com/p/django-intruder/

http://pypi.python.org/pypi/django-intruder

terça-feira, 15 de março de 2011

Boas práticas com Django

[Editado em 2011/03/27]: melhor explicado e detalhado o primeiro tópico.
 Depois dos tópicos de antipadrões com Django (http://pythonsmalltalk.blogspot.com/2011/03/discussao-sobre-django-internet-e.html), agora um tópico de boas práticas.
  • Usar filter e exclude somente dentro de managers ou models: Com django é tão fácil fazer query que acabamos inserindo filters e excludes em tudo quanto é local, tais como views e forms, o que é uma ideia terrível. Prejudica a testabilidade do código, mistura responsabilidades dos objetos etc.
  • Dar nomes às urls e usar reverse e a tag url: Usar urls hard-coded além de prejudicar a manutenção, ainda dificulta i18n. Além disso, a aplicação pode deixar de ser um "pluggable", ou seja, dificilmente poderá ser reaproveitada em outros projetos.
  • Utilizar select_related sempre que possível/necessário para otimização (http://docs.djangoproject.com/en/1.2/ref/models/querysets/#select-related)
  • Usar distinct em buscas que envolvem várias tabelas. Mais comumente quando são usados campos many to many para buscas. Isso é pra evitar que uma busca traga registros repetidos. Chatices de SQL que são propagadas nos resultados das buscas. (http://docs.djangoproject.com/en/1.2/ref/models/querysets/#distinct)
  • Criar Custom Fields caso um field siga um padrão (http://docs.djangoproject.com/en/1.2/howto/custom-model-fields)
  • Sempre dar redirect depois de salvar um formulário (básico de qualquer framework Web).
  • Não utilizar o arquivo tests.py. Criar uma pasta tests e adicionar arquivos de teste para arquivo da aplicação.
  • Há várias maneiras de organizar o settings. Uma básica e boa é criar (pelo menos) um arquivo de settings para desenvolvimento e um para produção.

domingo, 13 de março de 2011

Django Dynamic Fixture 1.2.1


Lançada nova versão da ferramenta (1.2.1). A documentação foi atualizada, incluindo comparação com outras ferramentas.

Antes dessa versão, a ferramenta atrapalhava a criação de objetos que tinham campos auto calculados, como é o caso dos objetos que usam a ferramenta Dango-MPTT (http://code.google.com/p/django-mptt).

Django Dynamic Fixture 1.2.1http://code.google.com/p/django-dynamic-fixture

quarta-feira, 9 de março de 2011

Discussão sobre Django, Internet e frameworks Web

Já mexi com muitos frameworks Web, de diferentes linguagens: JSP/Servlets, Struts, JSF, GWT, Echo2 (todos anteriores para Java), Django (Python), Grails (Groovy), Rails (Ruby) etc. Desses todos, destaco dois como sendo os mais inteligentes: Django e GWT.

Django porque é muito simples, legível e poderoso.

GWT porque foi criado pensando completamente em comandos assíncronos. Talvez apenas o Echo2 poderia se comparar a ele.

Ainda não existe um framework perfeito (ou quase), até mesmo porque a internet ainda é muito bagunçada. Prova disso são as próprias "linguagens" de HTML, Javascript e CSS que são completamente rebuscadas. Não é a toa que hoje existem diversas ferramentas para geração de CSS e ferramentas de Javascript, tais como JQuery, que não apenas criam funções bacanas para serem usadas, mas que também fazem uma série de correções e adaptações para navegadores e pro próprio HTML/Javascript para que o desenvolvimento Web se torne menos amaldiçoado.

Isso dá até um bom argumento para a Microsoft e o IE não adotarem certos padrões e convenções. Uma empresa do tamanho da Microsoft não deve acatar a padrões mal definidos. Claro que não estou defendendo a Microsoft, até porque isso só piora ainda mais a situação. Entretanto, é compreensível.

Mas enfim, onde quero chegar é que Django não é perfeito e, acredito, tem certas coisas que devem ser evitadas. Segue uma lista:

  • Framework de permissões: Acho útil apenas para interface de Admin. Para uso interno, não faz sentido. Devemos simplificar as coisas, não complicar. Logo, devemos trabalhar com grupos de usuários (vide django snippets). Perdemos em flexibilidade mas ganhamos em simplicidade e clareza.
  • Formsets, Inline Formsets etc: Foram criados pensando na interface de Admin. Apesar de quebrarem um galhão as vezes, são muito rebuscados e limitados.
  • Templates para comandos assíncronos: Templates no Django são muito legais, principalmente seu sistema de herança que é muito simples. Contudo, meu modo de ver é que templates é uma arquitetura pensando em páginas e comandos síncronos. Quando vamos trabalhar com chamadas assíncronas, eles perdem importância. Django não foi arquiteturado como o GWT, logo, não é trivial criar componentes de interface de usuário.
  • get_absolute_url: O quê tem a ver url com a base de dados? Isso é uma tentativa de DRY, mas, ao meu ver, equivocada. Primeiro porque deixa confuso aonde a url será definida (temos o urls.py pra isso). Depois porque mistura de responsabilidade da camada de dados/negócios com a de exibição.
  • Fixtures (estáticas) nos testes: Fixtures estáticas, não importa se é xml, yaml, json etc, são horríveis para manutenção. O máximo é ter um initial_data com usuários, grupos, permissões e algum outro dado básico e olhe lá.
À medida que for tendo novos pensamentos vou adicionando aqui.

domingo, 27 de fevereiro de 2011

Django Dynamic Fixture

Utilizar dados estáticos para testes é um antipadrão. Mesmo assim, o Django fornece facilidades para usar fixtures estáticas (yaml, json...) nos testes. Não use! A manutenção dos testes se torna péssima.

A melhor solução é criar os objetos dinâmicamente para cada caso de teste. Para facilitar, pode-se criar fixtures que criam instância de objetos já com dados populados. Melhor ainda, deixe que uma ferramenta faça isso por você, como é o caso da Django Dynamic Fixture: http://code.google.com/p/django-dynamic-fixture/

Instalação: pip install django-dynamic-fixture
Documentação: A documentação está toda na página inicial.

domingo, 29 de agosto de 2010

Django Pluggables

Alguns Django pluggables para funcionalidades rotineiras em Websites.

DjangoOpenID (http://code.google.com/p/djangoopenid): Para facilitar a integração do OpenID para autenticação em aplicações com Django. É uma solução bem simples, não indicado se você precisa de uma solução mais elaborada.

Django-WorldDB (http://code.google.com/p/django-worlddb): Para facilitar a criação de caixas de seleção “país/região/cidade”.

Django-ip2geo (http://code.google.com/p/django-ip2geo): Para descobrir o local de um usuário através de seu IP. Usa a base de dados livre do Maxmind.

Fontes:

http://www.maxmind.com/app/geolitecity
http://www.maxmind.com/app/python
http://www.maxmind.com/app/api
http://www.maxmind.com/app/installation?city=1
http://code.google.com/p/pygeoip/
http://www.ip2phrase.com/


Sua versão Django na Locaweb

Os servidores Linux da Locaweb, assim como os do Google App Engine, fornecem uma versão padrão do Django (0.96, 1.0 ..). Assim, basta configurar sua aplicação Django e pronto (http://wiki.locaweb.com.br/pt-br/Como_instalar_uma_aplicação_Django%3F). O detalhe é que o desenvolvimento do Django é muito ativo, vire e mexe tem versão nova e com MUITAS funcionalidades bacanas. Portanto, compensa sempre utilizar as versões mais novas do framework.

O problema é que nenhuma empresa (tem alguma?) consegue manter uma equipe para gerenciar milhares de versões de milhares de aplicativos de um servidor. É o que ocorre com a Locaweb e também com o Google (no caso do Google App Engine).

A melhor maneira para resolver isso é a solução proposta pelo Google App Engine, que também é aplicável nos servidores da Locaweb. Basta copiar o diretório da versão do Django que desejar na raiz do seu projeto, como se fosse um pluggable (Django = simplicidade + flexibilidade), e configurar o classpath apropriadamente. Resumindo a parte da configuração, basta utilizar o index.wsgi a seguir: 

Importante: Faça backup do index.wsgi original antes de qualquer mudança. import os, sys, site # Using Django of your project directory: # Remove the standard version of Django. for k in [k for k in sys.modules if k.startswith('django')]: del sys.modules[k] # Force sys.path to have our own directory first, in case we want to import from it. sys.path.insert(0, '/home/SEUUSUARIO/wsgi_apps/SEUPROJETO') sys.path.append('/home/ginlab/wsgi_apps/SEUPROJETO') os.environ['DJANGO_SETTINGS_MODULE']='settings' # se usa outras bibliotecas site.addsitedir('/home/SEUUSUARIO/.python/lib') import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() Fontes: http://code.google.com/appengine/articles/django.html

Sistema de autenticação/autorização das redes sociais

Para muitos sistemas, compensa mais utilizar um sistema de autenticação/autorização dos WebServices de redes sociais famosas (semelhante ao sistema de OpenID) do que implementar um módulo do zero. O primeiro passo é a criação de "contas de aplicação" (análogo a contas de usuário) nas redes sociais. Segue as URLs para cadastrar uma aplicação nas redes sociais mais famosas:

Facebook: http://www.facebook.com/developers/createapp.php
Twitter: http://twitter.com/apps
Orkut/Gmail/Google: https://www.google.com/accounts/ManageDomains
LinkedIn: http://developer.linkedin.com/docs/DOC-1008

Ainda, existem plugins que facilitam a integração dessas funcionalidades ao seu framework MVC-Web. Por exemplo, para Python-Django:

Social-Auth:
http://uswaretech.com/blog/2009/08/django-socialauth-login-via-twitter-facebook-openid-yahoo-google/
http://github.com/uswaretech/Django-Socialauth

PyFacebook:
http://code.google.com/p/pyfacebook/