Francisco Souza

Open source, Python, Django, Java, agile e outras coisas mais

Construindo Um CRUD Com Frameworks Python, Parte III: Web2py

Chegamos à terceira parte da sequência de tutoriais para construção de CRUDs utilizando frameworks Python. Nesta terceira parte, vou abordar o web2py, framework livre e leve, 100% escrito em Python, e baseado no Ruby on Rails e no Django. De acordo com o site oficial, “o web2py difere do Rails pois é escrito em Python” e, de acordo com o criador, por ser escrito em Python, o web2py é mais rápido e escalável que o Rails. Vale ressaltar que escalabilidade não é uma questão estritamente ligada à linguagem ou ao framework, mas sim ao design do software.Instalando o web2py

A instalação do web2py é tão simples, que não existe =P Na verdade, é necessário apenas baixar um zip com o código fonte, extrair o pacote, acessar o diretório do web2py e rodar o comando:

$ python web2py.py

Após perguntar uma senha para administração, o web2py começará a rodar uma aplicação de exemplo na porta 8000. Assim, basta acessar pelo browser o endereço http://127.0.0.1:8000 para navegar pela aplicação Hello World prontinha, pedindo para ser customizada. Aqui percebe-se também que não é preciso criar um projeto, ele já vem criado e podemos explorar desde já a estrutura que o web2py trabalha. Dentro do diretório web2py, temos uma estrutura com inúmeros diretórios. Por hora, vamos nos limitar ao diretório applications, que intuitivamente podemos concluir que armazena as aplicações :)

[caption id=”attachment_539” align=”aligncenter” width=”198” caption=”Estrutura de diretórios web2py”]Estrutura de diretórios web2py[/caption]

Dentro do diretório applications, encontramos três subdiretórios: admin, examples e welcome. São três aplicações padrão que o web2py inclui: uma interface administrativa, um aplicação com exemplos de uso do framework (uma espécie de documentação) e a aplicação welcome, esperando para ser personalizada. A interface administrativa do web2py também pode ser enxergada como uma IDE, em interface web. Tem até editor de texto com syntax highlighting. Para acessar esta interface, basta digitar no browser o endereço http://localhost:8000/admin. A senha em questão é a mesma informada quando o framework foi executado.

Para seguir com o CRUD de usuários da ABC Informática, vamos criar a aplicação usuarios. Para criar esta aplicação, acesse a interface administrativa (http://127.0.0.1/admin), insira a senha, digite “usuarios” na parte à direita “Create a new application”, aperte enter e pronto! =) Agora, dentro do diretório applications o web2py criou um subdiretório chamado usuarios com uma porrada de arquivos dentro. Podemos finalmente começar a trabalhar! o/

MVC no web2py

Ao contrário da esmagadora maioria de frameworks MVC, o web2py não utiliza classes para definir controladoras e/ou modelos. O Django não utiliza classes para os controllers as views, mas para praticamente todas as outras coisas utiliza classes. Pylons, Cake PHP, CodeIgniter e os frameworks Java vão pelo mesmo caminho. Confesso que no meu primeiro encontro com o web2py eu estranhei e me questionei, assustado: “uai, não tem classes? que estranho!”. Pois é, não tem classes e pode parecer estranho a princípio (principalmente se sua experiência com frameworks MVC venha do Java ou do PHP), mas depois se torna natural. (Parêntesis: tudo que parece estranho no começo e nós insistimos, se torna natural depois).

Assim, nossa camada de modelo é “representada” no web2py pelo arquivo db.py, que fica no diretório models. Os controllers são módulos Python que ficam no diretório controllers e as views são templates, guardados no diretório views. Os nomes dos diretórios são bastante sugestivos, não? Todos os diretórios dentro da aplicação têm nomes sugestivos, que já nos dão uma noção de sua funcionalidade.

Na camada de visualização, o web2py não trabalha com nenhuma linguagem de templates. Para a parte dinâmica, é utilizado Python puro (de forma semelhante ao que acontece no PHP). Lembrando que qualquer framework Python pode utilizar algumas linguagens de template baseadas em Python, como jinja2, Mako e Genshi. O motivo para optar por não usar uma linguagem de template é o desempenho. O criado do framework também se aproveita do fato da linguagem Python ser simples de ler, bem próxima de pseudo-códigos.

Agora, chega de teoria, e vamos à mão na massa…

Definindo o Model

Conforme visto acima, no web2py, definimos nossas tabelas utilizando a camada de abstração de dados (DAL - data abstraction layer) do web2py. Atualmente, a camada de abstração da suporte a diversos RDBMS, como sqlite3, MySQL e Oracle, e também ao BigTable.

Para definir a tabela usuarios, basta abrir o arquivo db.py, dentro do diretório models. Este arquivo é cheio de conteúdo, nem todos são úteis para nós neste momento, mas vamos deixar assim e simplesmente adicionar ao final do arquivo a definição da nossa tabela:

[cc lang=”python” wraplines=”false”]db.define_table(‘usuarios’, Field(‘nome’), Field(‘idade’, ‘integer’))[/cc]

Aí está, definimos nossa tabela, simples né?! E a tabela também é criada implicitamente pelo web2py, você também não precisa se preocupar com a criação da tabela. Por padrão, quando não definimos o tipo (segundo parâmetro de Field), o web2py cria o campo como tipo string. Também definimos no arquivo db.py a validação destes atributos, de forma bem intuitiva. Assim, adicionamos ainda ao fim do arquivo, o seguinte código:

[cc lang=”python” wraplines=”false”]db.usuarios.nome.requires = IS_NOT_EMPTY() db.usuarios.idade.requires = IS_NOT_EMPTY()[/cc]

Estas duas linhas informam que os campos não podem ser vazios. Agora que finalizamos a definição do nosso model, podemos partir para a próxima etapa =)

Controllers e URL’s no web2py

Assim como no Pylons, o web2py adota um padrão de URL controller/função (não há classes, portanto não há métodos), mas antes do nome do controller, entra o nome da aplicação. Assim, no web2py, o padrão de URL é <application>/<controller>/<action(function)>. Assim, a função index, do controller default.py, é acessada pelo endereço: http://localhost:8000/usuarios/default/index.

A renderização de templates no web2py ocorre de forma implícita. Para cada controller, temos um subdiretório dentro do diretório views com o mesmo nome do controller, e dentro deste subdiretório, temos um arquivo de template para cada action (função). Assim, a função index do controller default.py, acessa o template index.html dentro do diretório views/default de nossa aplicação.

CRUD Helper

Como eu não usei as generic views no outro post e o pessoal da comunidade Django voou no meu pescoço (hehe), resolvi usar o CRUD Helper do web2py (e logo logo faço um remake do post anterior incluindo as generic views). O CRUD Helper do web2py é muito fácil de usar. Para usá-lo, precisamos adicionar uma configuração no arquivo db.py e pronto. Na verdade, sequer precisar adicionar tal configuração, pois ela já vem configurada por padrão naquele monte de linhas que o web2py entrega no db.py. A configuração em questão é apenas uma linha:

[cc lang=”python” wraplines=”false”]crud=Crud(globals(),db)[/cc]

E pronto, já estamos pronto para usar o CRUD do web2py. Agora, basta chamar o CRUD Helper numa action de nosso controller e pronto, a mágica estará feita. Portanto, vamos ao nosso controller default.py e adicionaremos a action meu_crud:

[cc lang=”python” wraplines=”false”]def meu_crud(): return dict(form=crud())[/cc]

E pronto, a mágica já aconteceu. Nosso CRUD está configurado desta forma:

  • CREATE: /usuarios/default/meu_crud/create/usuarios;
  • READ: /usuarios/default/meu_crud/read/usuarios/<id_do_usuario> (e ainda o endereço /usuarios/default/meu_crud/select/usuarios para listar todos os usuários);
  • UPDATE: /usuarios/default/meu_crud/update/usuarios/<id_do_usuario>
  • DELETE: /usuarios/default/meu_crud/delete/usuarios/<id_do_usuario>

Pode até parecer trapaça, mas usando o CRUD Helper fazer CRUD vira brincadeira de criança. É importante explorar todas as características do framework, então vá em frente, e aproveite-se de todas as facilidades do web2py! =) No próximo post eu mostro como isso também é brincadeira de criança no Django utilizando as generic views.

O código fonte desta aplicação pode ser obtido no Bitbucket.