Django Brasil


Comunidade brasileira de Django


Feeds RSS

Envolva-se

O Django Brasil é um grupo de usuários e pesquisadores brasileiros de Django, uma framework para desenvolvimento ágil para a Web, baseada na linguagem Python e em padrões da programação orientada a objetos.

Listas de discussão

  • Usuários do Django no Brasil: Lista de discussão de ajuda ao Django em português.

    Inscreva-se na lista Django-Brasil
  • django-l10n-portuguese: Equipe de localização e tradução do Django para o português.

    Iscreva-se na lista de localização

Diga ao mundo

Casos de Sucesso

Diversas empresas adotam o Django a cada dia mais. Veja algumas histórias de grande satisfação que a opção pelo Django gerou.

Obtenha ajuda

Autores

Você escreve sobre Django em português? Avise-nos, e adicionaremos seu feed nesta página.

Comunidade

Esta página é atualizada a cada hora e agrega entradas dos blogs de brasileiros que escrevem sobre o Django.

Visão do Vale

Publicado ontem às 21h00
DjangoSites.org feed

Website of the journal Visão do Vale, a regional newspaper located in Vale do Caí, Rio Grande do Sul, Brazil (http://visaodovale.com.br/)

Leia essa entrada em seu contexto original »

Cristiana Arcangeli - Beauty & Well-Being

Publicado ontem às 21h00
DjangoSites.org feed

Home site of a very well-known Brazilian fashion consultant, specialized in Fashion, Health, Beauty and Well-Being. (http://cristianaarcangeli.terra.com.br/)

Leia essa entrada em seu contexto original »

ENECOMP 2009

Publicado em 26/06/2009 às 3h00
DjangoSites.org feed

National computer students metting. (http://enecomp.org.br/)

Leia essa entrada em seu contexto original »

Você gostaria de ver Django-flash incluído no Django como uma Contrib app?

Publicado em 19/06/2009 às 15h14
destaquenet feed

Django-flash, um despretencioso projeto de software livre desenvolvido pela Destaquenet, tem recebido excelentes críticas por quem o vem utilizando regularmente. Sua adoção vem crescendo vagarosamente, mas consistentemente. Nem preciso dizer o quanto isso é gratificante para nós. De um tempo para cá, eu fui contactado por alguns desses usuários perguntando sobre a possibilidade de ter o [...]

Leia essa entrada em seu contexto original »

Proxy Models: quase uma bala de prata

Publicado em 30/05/2009 às 21h00
Marinho Brandão feed

Há alguns acertos de design que são praticamente incontestáveis.

O novo recurso de classes de modelo do tipo "proxy = True" é um desses acertos.

Esta é uma das novidades da versão 1.1 (há, de fato, várias outras novidades na QuerySet que resolvem diversos outros problemas) que vão me ajudar bastante, do tipo que dá a tentação de reescrever muita coisa pra ficar mais elegante e compatível com a novidade.

Vamos partir da seguinte classe de modelo, que aliás, é um caso bastante comum em diversas situações:

from django.db import models

class Funcionario(models.Model):
    nome = models.CharField(max_length=50)
    vendedor = models.BooleanField(blank=True, default=False)
    gerente = models.BooleanField(blank=True, default=False)

    def __unicode__(self):
        return self.nome

Para registrar a classe "Funcionario" no Admin, você pode criar a classe "AdminFuncionario" no módulo admin.py da aplicação:

class AdminFuncionario(ModelAdmin):
    list_display = ('nome','vendedor','gerente')
    list_filter = ('vendedor','gerente')

Veja, temos aí um caso comum: um funcionário tem um nome, e pode ser, ora vendedor, ora gerente, ora ambos ou ora nenhum dos dois.

A consequência conhecida é que sempre é necessário usar de filtros, managers e outros meios para filtrar quando se deseja um dos 4 variantes de funcionários. Dentre as situações mais comuns que precisamos resolver estão:

  • Filtro através de ForeignKey em widgets de forms;
  • Registro da classe no Admin limitado a apenas uma vez;
  • Filtro através do manager (exemplo: Funcionario.objects.filter(vendedor=True));
  • Necessidade de forçar o valor de um dos campos de flag ("vendedor" e "gerente") sempre que for criar um novo objeto;
  • Filtros no Admin quando se deseja mostrar apenas vendedores ou gerentes;
  • Necessidade de forçar valores default quando criar ModelForms específicos para essa classe de modelo.

Bom, é provável que você já tenha passado por pelo menos uma dessas situações, e as soluções em geral envolvem todo tipo de gato, desde scripts utilizando JavaScript até métodos em managers, widgets, forms, etc.

Agora veja a solução, quando se cria classes de modelo proxy para resolver essa situação:

from django.db import models

class Funcionario(models.Model):
    nome = models.CharField(max_length=50)
    vendedor = models.BooleanField(blank=True, default=False)
    gerente = models.BooleanField(blank=True, default=False)

    def __unicode__(self):
        return self.nome

class VendedorManager(models.Manager):
    def get_query_set(self):
        qs = super(VendedorManager, self).get_query_set()
        qs = qs.filter(vendedor=True)
        return qs

class Vendedor(Funcionario):
    class Meta:
        proxy = True

    objects = VendedorManager()

    def save(self, *args, **kwargs):
        self.vendedor = True
        return super(Vendedor, self).save(*args, **kwargs)

class GerenteManager(models.Manager):
    def get_query_set(self):
        qs = super(GerenteManager, self).get_query_set()
        qs = qs.filter(gerente=True)
        return qs

class Gerente(Funcionario):
    class Meta:
        proxy = True

    objects = GerenteManager()

    def save(self, *args, **kwargs):
        self.gerente = True
        return super(Gerente, self).save(*args, **kwargs)

Observe que nada foi modificado na classe de modelo "Funcionario". Nem mesmo foi necessária alguma importação adicional.

Feito isso, você pode usar tranquilamente as novas classes "Gerente" e "Vendedor" naturalmente, em qualquer lugar. A distinção entre elas inclui:

  • Signals
  • Registro da classe no Admin
  • Forms
  • Filtros em fields de forms, como ModelChoiceField (que também vale para o Admin)
  • Filtros no Admin
  • Manager

Já tudo o mais que não for determinado manualmente, irá trabalhar de forma específica e transparente, vinculado à classe herdada.

Não serão criadas tabelas no banco de dados para esta classe, ela é totalmente abstrata, porém, tem o papel de trabalhar como interface para uma classe numa situação peculiar.

Veja como fica por exemplo o "admin.py" (agora o arquivo completo):

from django.contrib import admin
from django.contrib.admin.options import ModelAdmin
from django import forms

from models import Funcionario, Vendedor, Gerente

class AdminFuncionario(ModelAdmin):
    list_display = ('nome','vendedor','gerente')
    list_filter = ('vendedor','gerente')

class FormGerente(forms.ModelForm):
    class Meta:
        model = Gerente
        exclude = ('gerente',)

class AdminGerente(ModelAdmin):
    form = FormGerente

class FormVendedor(forms.ModelForm):
    class Meta:
        model = Vendedor
        exclude = ('vendedor',)

class AdminVendedor(ModelAdmin):
    form = FormVendedor

admin.site.register(Funcionario, AdminFuncionario)
admin.site.register(Vendedor, AdminVendedor)
admin.site.register(Gerente, AdminGerente)

Veja que agora cada uma delas tem seu próprio Admin ocultando os campos que forem desnecessários e completamente customizável (o que vale também para os templates customizáveis para o Admin).

É ou não é fantástico?

Leia essa entrada em seu contexto original »

Busca full-text do mysql no django

Publicado em 28/05/2009 às 15h16
Marcos Petry feed

Essa semana tive que implementar em um dos meus projetos um sistema de busca full-text. como estou utilizando o Mysql, ele possui um mecanismo de pesquisa integrado. Há outras bibliotecas de pesquisa como o Lucene, Xapian e Sphinx e todas elas possuem modulos para integra-las ao Django(django-search-lucene, djapian e django-sphinx ) mas no meu caso, como estou utilizando uma hospedagem compartilhada, tenho certas restrições para instalar algumas bibliotecas, portanto tive que partir para esta alternativa.

Bom, vamos ao que é necessário para funcionar a busca:

digamos que você possui um model de noticias:

class Artigo(models.Model):
data_publicacao = models.DateTimeField("Data de Publicação", default=datetime.now)
titulo = models.CharField(max_length=200)
slug = models.SlugField()
texto = models.TextField("Texto da noticia")

class Meta:
ordering = ['-data_publicacao']
get_latest_by = 'data_publicacao'

def __unicode__(self):
return self.titulo


Como esperado, o código acima vai gerar um tabela no banco, mas, para a busca funcionar corretamente, teremos que criar "no braço" um índice fulltext para efetuar a busca. Como estamos utilizando o mecanismo de busca do próprio banco. O índice será atualizado automaticamente quando registros são inseridos, atualizados, ou excluídos, de modo que os resultados da pesquisa nunca estarão desatualizada. A declaração CREATE INDEX é utilizado para criar o índice:
CREATE FULLTEXT INDEX fti_noticias_artigo ON noticias_artigo(titulo,texto)


Bom agora teremos que estender esta funcionalidade ao ORM do Django e criar um manager para o model em que você quer fazer a busca. Para isso simplesmente copie este código no seu models, ou melhor, coloque em um arquivos separado, já que você poderá aproveitá-lo em outros models!

Agora, chame o manager do código, atribuindo ao atributo objects (ou qualquer outro que você criar) passando como parâmetro os campos que você indexou no mysql:
objects = SearchManager(('titulo', 'texto'))


e está pronto!

agora para realizar alguma busca utilize o seguinte comando:

Artigo.objects.search('minha busca')


o método search executará uma consulta, verificando se a string que você enviou se encontra em um dos campos que você estabeleceu no seu SearchManager.

algo mais ou menos assim:
SELECT titulo, data_publicacao, slug, texto, MATCH(titulo, texto) AGAINST ('minha busca')
AS `relevance`
FROM noticias_artigo
WHERE MATCH(titulo, texto) AGAINST ('minha busca')


O seu manager também inclui um campo extra na sua consulta chamado relevance, que é o indice de relevância da sua pesquisa. Desse modo é possivel efetuar uma ordenacão através deste campo.

Artigo.objects.search('minha busca').order_by('relevance')


bom era isso! qualquer duvida, reclamação, ou colaboração de código, é só comentar!

Leia essa entrada em seu contexto original »

arthurfurlan's blog (my blog)

Publicado em 25/05/2009 às 20h00
DjangoSites.org feed

A simple blog engine using the django-diario application. (http://blog.arthurfurlan.org/)

Leia essa entrada em seu contexto original »

Hello world, again

Publicado em 25/05/2009 às 7h06
Arthur Furlan feed

merlin Yep, that's the second time I post a "Hello world" entry here. The reason is that I recently moved my domain from an account at Bluehost to a VPS at Linode. So, first of all, I would like to introduce you to merlin, my new VPS. :)

As I'm the sysadmin behind my server now, I decided to not install mod-php here and then I had to change my blog engine. I used to run Wordpress for years and now I'm running django-diario, a wonderful blog engine for django made by Brazilian djanglers.

About this new version of my old blog, you may have noticed that it has only this post... That's right, I removed the old stuff (in fact I just didn't migrate them from Wordpress) and I intend to start translating and re-posting a small part of them as soon as possible. If you want to see here any specific post from my old blog, please, let me know.

As you can see now I'm writing in English and I used to write in Portuguese... I'm not a professional English writer, so you won't be a lucky guy if you find some bugs around here and if you do find something, please, let me know about it and I will gladly fix it.

In my old blog I used to post mainly about ubuntu and php, from now on I will post more about python and debian. This time I'll also try to write more often and probably in small chunks.

I think that's all...

Leia essa entrada em seu contexto original »

Django UnicodeEncodeError com upload usando WSGI

Publicado em 13/05/2009 às 12h28
Enrico Batista da Luz feed

Se você se deparou com um UnicodeEncodeError ao fazer o upload de algum arquivo com caracteres especiais usando WSGI no Django, a solução pode estar aqui: How to use django with mod_wsgi – Additional Tweaking. Eu passei pelo seguinte erro: UnicodeEncodeError: 'ascii' codec can't encode characters in position 86-87: ordinal not in range(128) Em resumo é preciso alterar as [...]

Leia essa entrada em seu contexto original »

Câmara Municipal de Pato Branco

Publicado em 12/05/2009 às 0h00
DjangoSites.org feed

Câmara Municipal de Pato Branco (http://www.camarapatobranco.com.br/)

Leia essa entrada em seu contexto original »

Sera que eu compro?

Publicado em 12/05/2009 às 0h00
DjangoSites.org feed

O Será que eu compro? é a rede social das compras. Nosso propósito não é vender, mas sim estabelecer um canal para o debate sobre produtos e serviços, seja aqueles que são comercializados na web quanto aqueles que são comercializados fora dela. Comprou algo e gostou? Conte para os outros, deixe sua opinião aqui. Mas se comprou e não valeu a pena ou você acha que o atendimento e a qualidade estiveram abaixo do esperado, denuncie aqui com sua opinião. Por outro lado, se vai comprar algo, deixe aqui a sua pergunta, para que outras pessoas possam responder e te ajudar na escolha. Há também espaço para imagens e links sobre os produtos e serviços, pra faciliatr a escolha. Algumas imagens não vão ser nada boas, mas vão denunciar um produto ruim no mercado, e assim por diante. O mais importante é saber que a opinião mais importante é a de quem compra. Não adianta nada ouvir as belas propagandas de quem vende, é preciso saber o que os compradores acharam. (http://www.seraqueeucompro.com/)

Leia essa entrada em seu contexto original »

Imobiliária Vilmai

Publicado em 11/05/2009 às 23h00
DjangoSites.org feed

Website desenvolvido em Django. (http://www.imobiliariavilmai.com.br/)

Leia essa entrada em seu contexto original »

Como criar um site bacana em poucos dias

Publicado em 11/05/2009 às 8h00
Marinho Brandão feed

A minha satisfação com o "Será que eu compro?" não é só por ter tido uma boa ideia. A rapidez com que a coisa fluiu foi muito satisfatória.

Há uma semana atrás, numa tarde de sábado, eu coloquei a minha filha para dormir e estava com algum tempo sobrando. Algo em torno de 2 ou 3 horas. Tinha muito trabalho pra fazer, mas na verdade eu não estava afim, era sábado e eu queria só brincar um pouco.

Veio a ideia à cabeça e eu à coloquei em prática.

Algumas horas de trabalho depois e o site foi ao ar, na segunda-feira cedinho. Na terça com domínio registrado, tive condições de lançar os registros básicos de SEO para que os sites de busca pudessem começar a indexar o site.

Afora as horas de sono da Tarsila no fim de semana, e algum tempo no domingo enquanto assistia algo na TV, o tempo gasto foi muito pouco: os minutos de sobra durante a semana.

Como pode ver, foi muito pouco tempo pra ter o site publicado. E agora, vou listar abaixo aquilo que eu acho que foi decisivo pra isso, e que há algum tempo eu venho aprendendo e gostaria de passar a outros como boas práticas a serem lembradas.

1. Ter uma ideia fácil de ser colocada em prática

Não vou entrar na questão de se a ideia é boa ou não. Claro que se você tem uma ideia e quer fazer dela realidade, é porque você acredita nela e acha que é boa. E eu estou particularmente convencido de que boas ideias não são maiores do que um trabalho dedicado.

A questão é: você tem uma ideia possível de "entrar no ar" em etapas curtas?

Eu pessoalmente estou cansado de projetos longos. Especialmente aqueles ficam ainda mais longos à medida que o tempo passa. Um projeto pode ser imenso mas é importante que possa ser usado na prática o quanto antes, ainda que com poucas funcionalidades, mas sem deixar de ser interessante e útil.

O "Será que eu compro?" é uma ideia grande. O lista de "ideias" e "pendências" é maior que a lista de "funcionalidades ok" e vai tomar alguns meses para ficar "no jeito". Ainda assim, a lista de requisitos obrigatórios era pequena o suficiente para ir a público em menos de 10 ou 15 horas de dedicação.

Tente organizar o seu projeto de forma que a primeira versão seja viável o mais rápido o possível.

2. Usar um framework maduro e uma linguagem pragmática

Preciso dizer mais? Está óbvio que usar um framework maduro faz quase toda a diferença. O Django e o Python foram fundamentais nesse projeto. Diversas "coisinhas" que são feitas em 10, 15 ou 20 minutos só são possíveis usando um bom framework.

O Django é um framework com mais de 5 anos de vida, milhares de desenvolvedores que usam e sites construídos com ele, e uma comunidade muito ativa, especialmente no Brasil. O sistema de renderização de templates é fundamentalmente produtivo e a forma como o fluxo é distribuído entre Views, Models, Middlewares, etc. forma um conjunto produtivo e poderoso.

O Python é uma linguagem pragmática, simples e acessível, mas não é só isso. A vasta documentação na web e a quantidade de boas bibliotecas disponíveis fazem muita diferença na hora de fazer algo funcionar. Durante esta semana passei uns maus bocados ao usar o Lazarus para construiur uma aplicação desktop, isso porque precisava de um simples hash e boa comunicação com arquivos .MDB (Access) e Sqlite. A comunidade do Lazarus tem feito o melhor que pode por dele, mas a falta de documentação e de bibliotecas estão dificultando muito o trabalho. No Python este problema raramente existe.

Evidentemente há outros excelentes frameworks como Ruby On Rails, Merb e Pylons que são igualmente produtivos e maduros, há linguagens como Ruby, PHP e outras. Enfim, o desenvolvimento "ágil" não se resume só a essas ferramentas, mas há uma separação muito clara do que é ágil e maduro para o que não é.

3. Ter algumas utilidades prontas e reusáveis

Eu tenho um conjunto extenso de utilidades que inclui o django-plus, algumas utilidades relacionadas à realidade brasileira e outras coisas soltas por aí, mas para este caso específico eu usei um pequeno conjunto de aplicações plugáveis que eu usei no AprendendoDjango.com e no meu site pessoal, que inclui as seguintes utilidades:

  • Wiki/Flatpages
  • Blog
  • Galeria de imagens

Com essas três aplicações, é possível construir qualquer site básico visualmente, a partir do próprio site já no ar. Adicione a isso um conjutno bem bolado de códigos para cache de páginas e imagens (usando memcached), sitemaps, contato, etc. e você tem uma base reusável e prática para construir o seu site.

4. Usar e abusar de APIs maduras da Web2.0

Está aí uma grande sacada. Hoje a web possui diversos serviços de APIs para todo tipo de utilidade: imagens, vídeos, buscas, notícias, blogs, autenticação, etc. Tanto para publicar quanto para pesquisar. A lista inclui em destaque:

Usando uma API madura e conceituada disponível na Web, o seu trabalho caminha incrivelmente rápido e ganha outro nível de qualidade, basicamente é o novo conceito de "não re-inventar a roda" da Web 2.0.

5. Usar o deploy mais prático e "pronto" o possível

O local e modelo de hospedagem utilizados pode fazer muita diferença também.

No caso do "Será que eu compro?" o serviço de hospedagem utilizado é o Google App Engine (GAE). Ele tem a qualidade matadora de resolver alguns problemas sérios numa paulada só: performance, escalabilidade, praticidade e algumas questões mais importantes que envolvem hospedagem de sites, e faz uso da arquitetura de cloud computing do Google.

Com o uso de versões diferentes, você pode manter mais de uma versão do site, uma para testes de novidades e outra para a versão em produção. Com o uso de boas práticas no uso de Ajax e cache, aliados à escalabilidade natural do GAE, o site fica muito escalável.

Quer um exemplo? Neste site evitei algumas práticas comuns que utilizei ao longo dos anos: nas páginas renderizadas não há em nenhum lugar referências diretas ao usuário logado ou a outras funcionalidades mais "dinâmicas". Desta forma, essas páginas são renderizadas para o cache com expiração em 30 dias.

E o que eu fiz pra evitar problemas com isso? Simples. Criei um decorator que substitui o cache_page (do Django) com um algorítimo próprio para armazenar as páginas renderizadas em cache, usando uma chave baseada na URL e na QUERY_STRING. Desta forma, uma outra função faz o trabalho de cache invalidate quando os objetos relacionados são modificados. O código que faz isso está disponível no django snippet 1493. Assim, o cache só expira quando é descartado (isso é gerenciado pelo próprio memcache), quando um objeto relacionado é modificado ou quando se passam 30 dias.

A outra solução adotada foi fazer uso de Ajax para carregar elementos relacionados diretamente ao usuário, como é o caso do painel do usuário na página inicial e a votação.

Também evitei coisas como timesince e em breve quero criá-lo em JavaScript para que as datas sejam "calculadas" no lado cliente, a partir de uma data em formato UTC.

Esse tipo de técnicas adotadas permitiriam até mesmo a geração de arquivos HTML estáticos para as páginas, e como o cache é armazenado em memória, a performance e escalabilidade são as melhores que já consegui construir.

Por fim, outras ferramentas importantes que utilizei foram:

  • FreeDNS - para administrar os registros de DNS
  • Google Apps - para hospedar o domínio, e-mails e documentos.

Igualmente práticos e seguros, facilitam muito o nosso trabalho.

6. Usar boas ferramentas de SEO

Após colocar o site no ar e dar a ele o acesso publico, obviamente o que queremos é ver o maior número de gente usá-lo e apontar sugestões, críticas, bugs, elogios, etc.

Para isso, é importante conseguir o melhor posicionamento possível nos sistemas de busca.

Neste caso, além de adotar algumas das boas práticas de webstandard conhecidas, é importante tomar o cuidado para construir um bom Sitemap e um consistente (e de preferência também simples) robots.txt.

Uma das ferramentas obrigatórias de SEO é o Google Webmaster Tools. É ali que se registra o site, envia e valida os Sitemaps e o robots.txt. É ali também que podemos apontar algumas otimizações no direcionamento do site para determinados países e idiomas, tempo de varredura e palavras-chave preferidas. Ferramenta obrigatória pra quem quer ter uma chance a mais de acertar.

7. Buscar as boas ideias dos amigos

De nada vale um profissional sem seus amigos e parceiros. Como disse uma vez Isaac Newton: "se enxerguei mais longe, é porque me apoiei sobre ombros de gigantes". Não que a minha humildade tenha ido passear em algum lugar nesse fim de semana, não há qualquer comparação com Newton aqui, apenas inspiração.

O melhor que pude fazer assim que o site foi ao ar foi buscar as pessoas que considero mais importantes de ouvir nesse assunto. Claro que não me lembrei de todas, mas quando me lembro, envio uma mensagem perguntando, pedindo advice.

E a essência da pergunta é sempre a mesma: o que acha da ideia e o que fazer para que ela se torne realidade?.

As respostas que chegaram até agora inspiraram este artigo e algumas melhorias no site. Outras vão inspirar mudanças futuras e há ainda aquelas que me fizeram rever (ou pelo menos planejar isso) alguns elementos do site.

8. Persistência e dedicação

Por fim, o maior dos desafios.

Não há solução perfeita nem mesmo eterna e a web é campo vasto para experimentações. Mas o objetivo é sempre melhorar.

Eu acredito que o maior desafio não é ter uma grande ideia. O maior desafio também não é técnico. Por incrível que pareça, também não acredito que seja financeiro. Não acredito que rios de dinheiro mudariam muito a chance de sucesso da ideia.

Criar não é exatamente uma grande façanha. Grandes façanhas são resultados de anos de trabalho duro. Os grandes inventores e teóricos científicos sabem muito bem disso. Grandes visionários que são referências para nós também. Se Bill Gates, Sergey Brin e Steve Jobs ficaram ricos, é porque foram muitos anos de trabalho duro, 15 ou 18 horas por dia.

Eu acredito que o grande desafio é sempre a persistência. Eu já venci e já fracassei nesse ponto, e espero vencer de novo desta vez.

É a persistência que faz um produto desconhecido perambular por anos no desconhecido até crescer rapidamente na popularidade, e em se tratando de um site de social, isso é ainda mais importante, pois sem conteúdo, não há motivo para alguém se interessar pelo site.

Portanto, esse é o gigante a ser vencido agora.

No mais, espero que as dicas lançadas aqui sejam úteis a você, e quem sabe você também coloque uma boa ideia em prática e sejamos parceiros? Porquê não?

Leia essa entrada em seu contexto original »

V2 WindCenter

Publicado em 06/05/2009 às 23h00
DjangoSites.org feed

V2 WindCenter is a windsurf and kitesurf club in João Pessoa-PB, Northeast of Brazil. A perfect spot to sail all the year, with beautiful beaches and pleasant temperature. The V2 club offers windsurf and kitesurf lessons, equipments rental, sale and storage. (http://www.v2windcenter.com.br/)

Leia essa entrada em seu contexto original »

Igor Sobreira's weblog

Publicado em 05/05/2009 às 22h00
DjangoSites.org feed

This is my personal weblog, where i write mostly about Python and Django. Unfortunately just in Portuguese, for now. (http://igorsobreira.com/)

Leia essa entrada em seu contexto original »


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