Voando com o Django no Google App Engine
O Google App Engine é uma ferramenta sensacional para desenvolvedores web. Uma ferramente certamente útil e que deveria pelo menos ser experimentada por todo desenvolvedor web que se preza :) A primeira linguagem de programação suportada pelo App Engine foi o Python, e hoje a linguagem Java também é suportada. Python é uma linguagem com muitos frameworks web (muitos mesmo), e você pode usar alguns deles no App Engine. Resolvi, então, criar uma série com três posts sobre como usar três frameworks web Python no Google App Engine: Django, Flask e web2py.
Em todos os casos, desenvolverei uma aplicação simples, que será enviada para o Google App Engine e disponibilizada publicamente :) Nesta primeira parte, abordarei o Django, o mais famoso dentre os frameworks Python para a web.
O principal recurso do Django é a camada de modelo, chamada Django models. Trata-se de uma camada de abstração de dados composta por um poderoso framework de mapeamento objeto-relacional, que suporta diversos sistemas de gerenciamento de banco de dados relacionais. O único problema é que o Google App Engine não usa um banco de dados relacional, o App Engine usa o BigTable, um poderoso banco de dados para armazenamento de dados em larga escala. Assim, a poderosa camada de modelo do Django é simplesmente inútil, pelo menos nativamente falando.
Não há motivo para pânico, existe um fork do Django, o projeto django-nonrel, que visa trazer o poder do Django models para bancos de dados não-relacionais, como o BigTable. Na aplicação deste post, foi utilizado o subprojeto djangoappengine, que une o Django ao BigTable de forma descomplicada.
A aplicação de exemplo não será nenhum exemplo de criatividade: um blog extremamente simples, com apenas uma página para listar os posts e outra para cadastrá-los (protegida por login). Vamos utilizar a autenticação nativa do Django, e não a API de autenticação fornecida pelo App Engine.
O primeiro passo é deixar o ambiente pronto para receber nosso código (e voar em produção =P). De acordo com a documentação oficial do djangoappengine, é necessário baixar quatro arquivos e juntá-los. Comecei pela aplicação, baixei o arquivo django-testapp.zip, extraí e renomeei o diretório de django-testapp para blog_gae. Depois eu baixei as outras bibliotecas, de forma que a estrutura do projeto ficou da seguinte forma:
O diretório “django” foi extraído do pacote django-nonrel.zip, o diretório “djangoappengine” do pacote djangoappengine.zip e o “djangotoolbox” extraído do pacote djangotoolbox.zip. Junto à estrutura de exemplo da aplicação está presente o arquivo app.yaml, que é o arquivo de configuração da aplicação no Google App Engine. Neste arquivo, é necessário apenas mudar o ID da aplicação (primeira linha). Veja como fica o arquivo após a mudança:
version: 1
runtime: python
api_version: 1
default_expiration: '365d'
handlers:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
- url: /_ah/queue/deferred
script: djangoappengine/deferred/handler.py
login: admin
- url: /media/admin
static_dir: django/contrib/admin/media/
- url: /.*
script: djangoappengine/main/main.py
A cada parte da série de posts eu vou fazer o deploy de uma versão diferente, assim, todas as versões ficarão disponíveis online dentro de uma mesma aplicação do Google App Engine. Como esta é a primeira parte, então será a primeira versão =P Outro ponto é o arquivo de configuração do Django (settings.py), neste momento, a única mudança neste arquivo é “descomentar” a linha django.contrib.auth na tupla INSTALLED_APPS, para que possamos utilizar a aplicação de autenticação nativa do Django.
Agora nosso ambiente está devidamente configurado, podemos iniciar uma nova aplicação Django e começar a codar. A forma de iniciar a aplicação é a mesma de sempre (daqui pra frente, tudo se parecerá naturalmente Django): basta rodar o startapp.
$ ./manage.py startapp core
Criamos a aplicação principal do projeto, chamada core. É criado o diretório da aplicação com os módulos Python “normais”: models, views e tests. Vamos então criar o model Post. Note que tudo está em inglês, pois esta aplicação foi desenvolvida em inglês :) Eis o código do módulo models.py, com a classe Post:
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length = 200)
content = models.TextField()
date = models.DateTimeField(auto_now_add = True)
user = models.ForeignKey(User)
Agora basta instalar a aplicação core colocando-a dentro da tupla INSTALLED_APPS no arquivo settings.py. Como vamos utilizar a aplicação de autenticação do Django, vamos criar um usuário de administração (super-usuário) para gerenciar toda a bagunça:
$ ./manage.py createsuperuser
Após informar o nome de usuário, o e-mail e a senha, o usuário estará criado no banco de dados. Agora vamos fazer nossa aplicação estar preparada para fazer login e logout. Primeiro, vamos mapear as URLs de login e logout no arquivos urls.py:
urlpatterns = patterns('',
('^$', 'django.views.generic.simple.direct_to_template',
{'template': 'home.html'}),
('^login/$', 'django.contrib.auth.views.login'),
('^logout/$', 'django.contrib.auth.views.logout'),
)
Note as linhas 6 e 7, onde as URLs são mapeadas. Você pode também conferir os códigos dos templates registration/login.html e registration/logged_out.html. Finalmente, basta adicionar três linhas ao settings.py:
LOGOUT_URL = '/logout/'
LOGIN_REDIRECT_URL = '/'
Agora as URLs de login e logout já estão prontas para voar, podemos criar nossas views de cadastro e listagem dos posts. Vamos primeiro criar a view de cadastro, que contará com um formulário composto pelos campos title (título) e content (conteúdo). Será um ModelForm atrelado ao modelo Post. Além dos campos title e content, o atributo user do modelo Post será preenchido automaticamente com o usuário logado. Eis o código completo do formulário:
class Meta:
model = Post
exclude = ('user',)
def save(self, user, commit = True):
post = super(PostForm, self).save(commit = False)
post.user = user
if commit:
post.save()
return post
Agora basta criar a view para cadastro de um post. Vamos criar também a view de listagem com um simples redirecionamento para que as coisas funcionem bem aqui. Eis o código do módulo views.py:
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from forms import PostForm
@login_required
def new_post(request):
form = PostForm()
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save(request.user)
return HttpResponseRedirect(reverse('core.views.list_posts'))
return render_to_response('new_post.html',
locals(), context_instance=RequestContext(request)
)
def list_posts(request):
return HttpResponseRedirect('/')
Agora, para que a view new_post funcione, precisamos apenas mapear as duas views acima para suas respectivas URLs, e criar o template new_post.html. Eis o mapeamento de URLs:
('^posts/$', 'core.views.list_posts'),
Confira também o template new_post.html.
Finalmente já podemos ver alguma coisa através do navegador. Rodando o comando ./manage.py runserver no terminal temos o servidor inicializado, então é possível acessar a URL http://localhost:8000/posts/new no navegador para ver um formulário de cadastro de posts, onde os posts podem ser escritos e salvos (lembre-se apenas que é necessário efetuar login para acessar esta view). Agora, precisamos apenas listar todos os posts na URL /posts/. A view list_posts já está mapeada para a URL /posts/, então a única coisa a fazer é escrever o código da view, que lista todos os posts do banco de dados e envia para um template:
posts = Post.objects.all()
return render_to_response('list_posts.html',
locals(), context_instance=RequestContext(request)
)
Confira o template list_posts.html. Finalmente nossa aplicação está pronta para o deploy, mas como fazemos isso? De uma maneira muito difícil:
$ ./manage.py deploy
Pronto, aplicação em produção :) Para poder ter acesso como usuário na aplicação, basta apenas rodar o comando para criar o usuário remotamente:
$ ./manage.py remote createsuperuser
Você pode ver esta aplicação voando neste link: http://1.latest.gaeseries.appspot.com/ (para logar-se no sistema, utilize o nome de usuário demo com a senha demo)
E também ver o código fonte completo neste link: http://github.com/fsouza/gaeseries/tree/django
Nos vemos na próxima parte ;)


Eu estou desenvolvendo um projeto para rodar no App Engine. No meu caso, está sendo implementado em Java com o Google Web Toolkit, e até agora estou achando essa dupla uma excelente plataforma para desenvolvimento.
O bom do GAE é que você tem uma quota gratuita que te permite manter a sua aplicação no ar sem custos mesmo que ela ainda não te dê retorno financeiro. E assim que se fizer necessario você compra os recursos computacionais que precisar a preços bem interessantes
[...] This post was mentioned on Twitter by Jeveaux, Francisco Souza. Francisco Souza said: Voando com o Django no Google App Engine: http://bit.ly/bcE1No [...]
Parabéns pela iniciativa, excelente post.
[...] Francisco Souza Open source, Python, Django, Java, Ruby on Rails, agile e outras coisas mais Pular para o conteúdo InícioSobreComunidadeContato ← Voando com o Django no Google App Engine [...]
[...] da série de posts sobre o uso de frameworks Python no Google App Engine. Após abordar o uso do Django e do web2py no App Engine, agora veremos como usar o Flask, um microframework para Python baseado [...]
Parabens pelo post. Eu gostei muito e estou usando para adquirir conhecimento sobre Google App Engine e Django.
Muito bom! Mas acho que vc pode ser ainda melhor se de fato quiser ser um multiplicador eficiente. Digo isto por que sou um usuário windows e não consegui repetir seu sucesso. Como não conheço nenhuma das duas ferramentas fiquei perdido no meio do caminho. Faltou alguma coisa. Contudo achei a idéia espetacular e muito prática.
Parabens!