Anda di halaman 1dari 89

Mdulo

1 Bsico

{{ Desenvolvimento web com Python e web2py }}

Objetivo: introduzir os alunos ao desenvolvimento web com Python, utilizando o web2py como ferramenta, e apresentar todas as vantagens da utilizao de um framework. Para acompanhar o treinamento, os pr-requisitos necessrios so conhecimentos bsicos de HTML, CSS e lgica de programao (em qualquer linguagem).

[ w w w . w e b 2 p y b r a s i l . c o m . b r , w w w . t e m p o r e a l e v e n t o s . c o m . b r ]

{{ Desenvolvimento web com Python e web2py }}

>>> for pgina in pginas: print pgina


Introduo ..............................................................................................................................................................................4 O que web2py?..................................................................................................................................................................4 Princpios ................................................................................................................................................................................6 Conceitos bsicos da linguagem Python....................................................................................................................7 Executando o Python .........................................................................................................................................................7 Modo interativo....................................................................................................................................................................7 Ol Mundo em Python .......................................................................................................................................................8 Clculos....................................................................................................................................................................................8 Objetos .....................................................................................................................................................................................9 Tipos dinmicos................................................................................................................................................................ 10 Interpolao de variveis em strings....................................................................................................................... 11 Estruturas de dados ........................................................................................................................................................ 11 Listas ...................................................................................................................................................................................... 11 Sintaxe ................................................................................................................................................................................... 11 Operaes com listas ....................................................................................................................................................... 12 Tuplas..................................................................................................................................................................................... 12 Dicionrios........................................................................................................................................................................... 13 Sobre endentao ............................................................................................................................................................. 15 Iterao de elementos..................................................................................................................................................... 15 Expresses condicionais................................................................................................................................................. 17 lambda................................................................................................................................................................................... 18 Executando cdigo pr-determinado....................................................................................................................... 18 Comentrios e docstrings .............................................................................................................................................. 18 Mdulos ................................................................................................................................................................................. 19 List Comprehensions........................................................................................................................................................ 20 WSGI....................................................................................................................................................................................... 21 O Padro MVC .................................................................................................................................................................... 22 Preparando o ambiente de desenvolvimento ...................................................................................................... 23 Criando sua primeira aplicao.................................................................................................................................. 25 Camadas, mdulos e pacotes do web2py............................................................................................................... 28 A partir do zero ................................................................................................................................................................. 28 Modelos (models)............................................................................................................................................................. 29 Controladores (controllers)......................................................................................................................................... 32 Vises (views).................................................................................................................................................................... 33 Criando uma viso............................................................................................................................................................ 34 Passagem de argumentos para a viso................................................................................................................... 35 ciclo de vida da aplicao.............................................................................................................................................. 36 A camada de acesso a dados - DAL ........................................................................................................................... 37 Representao de registros .......................................................................................................................................... 39 Interagindo com a DAL .................................................................................................................................................. 40 Insert, Select, Update, Delete........................................................................................................................................ 41 Query ...................................................................................................................................................................................... 42 Atalhos................................................................................................................................................................................... 43 Ordenao............................................................................................................................................................................ 44 Query mltipla ................................................................................................................................................................... 44 Contagem de registros.................................................................................................................................................... 44 Alterao de registros..................................................................................................................................................... 44 Tipos de dados.................................................................................................................................................................... 45 Atributos ............................................................................................................................................................................... 45 Migraes............................................................................................................................................................................. 46 Validadores ......................................................................................................................................................................... 46
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

Os validadores de formulrio ...................................................................................................................................... 46 Os validadores de banco de dados............................................................................................................................. 48 Auto complete widget .................................................................................................................................................... 49 Mo na Massa - Viso Geral.......................................................................................................................................... 53 O Projeto ............................................................................................................................................................................... 53 Loja de Carro ...................................................................................................................................................................... 53 API........................................................................................................................................................................................... 63 Objetos globais:.................................................................................................................................................................. 63 Navegao: .......................................................................................................................................................................... 63 internacionalizao (i18n): ......................................................................................................................................... 63 Helpers (bibliotecas auxiliares): ................................................................................................................................ 63 Validadores: ........................................................................................................................................................................ 63 Banco de dados:................................................................................................................................................................. 64 Autenticao e Controle de Acesso........................................................................................................................... 69 Autenticao ....................................................................................................................................................................... 70 Restringindo acesso ......................................................................................................................................................... 72 Restrioes no registro de usurios............................................................................................................................. 72 Integrao com autenticao externa: Facebook, Google, Twitter etc..................................................... 72 Autorizao ......................................................................................................................................................................... 73 Formulrios......................................................................................................................................................................... 78 Validao de formulrios .............................................................................................................................................. 80 CRUD....................................................................................................................................................................................... 84 JQuery.................................................................................................................................................................................... 86 Ajax ......................................................................................................................................................................................... 87 web2py na web ................................................................................................................................................................. 88 Onde encontrar ajuda:.................................................................................................................................................... 88 Onde contribuir: ................................................................................................................................................................ 88 Recursos:............................................................................................................................................................................... 88 Instrutores: ......................................................................................................................................................................... 89 Bruno Cezar Rocha........................................................................................................................................................... 89 lvaro Justen....................................................................................................................................................................... 89

{{ Desenvolvimento web com Python e web2py }}

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

{{ Desenvolvimento web com Python e web2py }}

Introduo O que web2py?


web2py um framework para desenvolvimento Web escrito em Python, software livre e gratuito, que tem como um de seus principais objetivos proporcionar agilidade no desenvolvimento de aplicaes web seguras, baseadas em bancos de dados. O framework segue o modelo MVC (Model-View-Controller), que permite melhor organizao do cdigo. Ele tambm autocontido, ou seja, tudo o que voc precisa para desenvolver alguma aplicao est nele, basta baixar e descompactar para comear - nada de configuraes! Com o foco em permitir que o desenvolvedor pense apenas na aplicao que est desenvolvendo, o web2py possui integrao com mais de 10 sistemas de banco de dados e vrios subsistemas, como: criao automtica de formulrios com validao automtica; autenticao e autorizao; gerador de cdigos AJAX para melhor interao do usurio com a aplicao; upload seguro de arquivos; sistema de plugins; integrao com vrios padres web (XML, RSS etc.), dentre outros. O web2py leva em considerao todas as questes referentes segurana da aplicao web, e isso significa que o framework se preocupa em tratar as vulnerabilidades aplicando prticas bem estabelecidas, como, por exemplo, validando formulrios com preveno de injeo de cdigo malicioso; efetuando o correto escape da sada HTML para prevenir ameaas como o cross-site scripting e renomeando os arquivos de upload utilizando hash seguro. O web2py toma conta, automaticamente, de questes de segurana.

Segurana do web2py www.pythonsecurity.org/wiki/web2py/ O web2py possui uma camada de abstrao de banco de dados (DAL) que gera dinamicamente todo o cdigo SQL. A classe DAL pode se conectar e lidar de forma transparente com os bancos de dados:

SQLite MySQL PostgreSQL MSSQL FireBird Oracle IBM DB2 Informix Ingres Google BigTable on Google App engine GAE

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

{{ Desenvolvimento web com Python e web2py }}

A partir da definio de um ou mais bancos de dados para uma aplicao, o web2py gera uma interface administrativa bsica para acesso aos dados, no necessitando o uso de ferramentas para executar tarefas de administrao. Em uma nica aplicao, o web2py pode se conectar com vrios bancos de dados ao mesmo tempo, podendo facilmente integrar dados entre MySQL e Oracle, por exemplo. A aplicao de administrao, que acompanha a instalao padro do framework, prov uma interface administrativa que oferece todos os recursos para o desenvolvimento web:

Criao de novas aplicaes Edio de cdigos Python, HTML, JavaScript Upload de arquivos estticos como imagens e pacotes compactados Gerenciamento de arquivo de recurso de linguagem Sistema de tickets para acompanhamento do log de excees geradas na aplicao Atualizao automtica do framework Interface para o sistema de controle de verses (Mercurial)

Podendo ser executado com CPython (a implementao padro da linguagem Python implementada em C) ou com Jython (a implementao do Python escrita em Java), o web2py funciona com quase todos os seus recursos na plataforma gratuita de hospedagem de aplicaes do Google, o GAE (Google App Engine). O web2py Open Source sob a licena GPL2, mas as aplicaes desenvolvidas com o web2py no esto sujeitas a este tipo de licenciamento, ou seja, voc pode desenvolver suas aplicaes web2py e licenciar da maneira que escolher, seja open source ou software comercial. O web2py oferece a possibilidade de compilar as aplicaes em byte-code para distribuio com cdigo fechado. [ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ] 5

{{ Desenvolvimento web com Python e web2py }}

Outra caracterstica do web2py o compromisso com a compatibilidade em verses futuras - compromisso que tem sido mantido desde a primeira verso. Isso significa que as aplicaes desenvolvidas em uma verso especfica do framework funcionaro em verses mais recentes, sem que seja necessria nenhuma alterao de cdigo.

Princpios
A linguagem Python tipicamente segue os seguintes princpios

No se repita (DRY) Deve existir apenas uma maneira bvia para fazer algo Explcito melhor do que implcito O web2py procura seguir rigorosamente os dois primeiros princpios, para estimular o desenvolvedor a utilizar boas prticas de engenharia de software, seguindo um bom padro de projeto (MVC) e incentivando o reaproveitamento de cdigo. O framework guia o desenvolvedor, facilitando as tarefas mais comuns em desenvolvimento para web. Diferente de outros frameworks, o web2py aplica parcialmente o terceiro princpio. Com a inteno de prover o desenvolvimento gil, o framework efetua configuraes, importa mdulos e instancia objetos globais como session, request, cache,Translation. Tudo isso feito automaticamente, com a inteno de evitar, ao mximo, que o desenvolvedor tenha que importar os mesmos mdulos e instanciar os mesmos objetos no incio de cada model ou controller. Efetuando automaticamente estas operaes, o web2py evita problemas e mantm o princpio de no se repetir e de que deve existir apenas uma maneira para se fazer algo. Porm, se o desenvolvedor desejar, este comportamento pode ser alterado, possibilitando que em qualquer cenrio seja possvel importar mdulos (como ocorre em qualquer outra aplicao ou framework Python). Este treinamento objetiva introduzir os alunos ao desenvolvimento web com Python, utilizando o web2py como ferramenta, e pretender apresentar todas as vantagens da utilizao de um framework. Para acompanhar o treinamento, os pr-requisitos necessrios so conhecimentos bsicos de HTML, CSS e lgica de programao (em qualquer linguagem).

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

{{ Desenvolvimento web com Python e web2py }}

Conceitos bsicos da linguagem Python


uma linguagem de programao dinmica de altssimo nvel, orientada a objetos, interpretada, interativa e de tipagem dinmica e forte. utilizada em larga escala por empresas como Google, Yahoo, Dreamworks e Industrial Light & Magic. No Brasil, utilizada pela Locaweb, Globo.com, SERPRO, Interlegis (rgo vinculado ao Senado Federal), entre outros. Diversos softwares como GIMP, Inkscape e Blender3D utilizam a linguagem Python para extenses e criao de plugins. Abordaremos apenas os conceitos bsicos da linguagem, para apresent-la queles que esto iniciando no mundo da programao, ou queles que j programam, mas em outras linguagens. Para uma abordagem mais profunda de todos os aspectos da linguagem, sugerida a leitura do material encontrado no site oficial da linguagem: http://www.python.org.br

Executando o Python
Esta apostila no abordar a instalao do interpretador Python. A maioria dos sistemas operacionais baseados em Unix, como Ubuntu, MacOs e outras distribuies Linux, j costumam vir com Python instalado. O Python tambm pode ser instalado/executado em qualquer verso do Windows; para isso, basta seguir as dicas de instalao encontradas em http://www.python.org.br Considerando que seu sistema operacional j esteja pronto para executar o interpretador Python em modo interativo, inicie uma janela de terminal Linux/Unix/MacOS, ou um prompt de comando no Windows, e digite:
1. python

Modo interativo
Ao iniciar o interpretador Python, ser carregado um console interativo. Qualquer comando digitado neste console ser interpretado pelo Python.
1. 2. 3. 4. Python 2.6.5 (r265:79063), Apr 16 2010, 13:09:56) [GCC 4.4.3 on linux2 Type "Help", "copyright","credits" or "licence" for more information. >>>

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

{{ Desenvolvimento web com Python e web2py }}

Ol Mundo em Python
O comando print imprime qualquer objeto que seja do tipo string ou que possa ser serializado como string. Isso vale para textos, nmeros, objetos, estruturas de dados e muito mais.
1. 2. 3. 4. 5. Python 2.6.5 (r265:79063), Apr 16 2010, 13:09:56) [GCC 4.4.3 on linux2 Type "Help", "copyright","credits" or "licence" for more information. >>> print "Ol Mundo' Ol Mundo

No console interativo no obrigatrio utilizar a funo print para imprimir alguma coisa, pois neste modo o Python sempre responde com o retorno padro do objeto. Portanto, omitindo o comando print... 1. >>> 'Ol Mundo' 2. Ol Mundo ... teremos o mesmo resultado. Mas fique atento, sempre que escrevemos programas em arquivos .py, necessrio utilizar a funo print.

Clculos
O Console Python responde a operadores matemticos da mesma forma que uma calculadora.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. >>> (5+2)*9 63 >>> 50+50 100 >>> 7/2 3 # Ops tem algo errado, 7/2 no 3.5? Sim mas neste caso Python arredonda para baixo >>> 7.0/2 3.5 # passando um nmero do tipo **float** o retorno tambm ser **float** >>> "Brasil "*3 # Python tambm multiplica **strings** 'Brasil Brasil Brasil'

A Linguagem Python prov dois comandos para obter documentao a respeito de objetos definidos no escopo atual da memria. Podemos, por exemplo, chamar o comando help passando um objeto qualquer como parmetro:
1. >>> help(objeto)

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

{{ Desenvolvimento web com Python e web2py }}

Objetos
Em Python, qualquer coisa um objeto: uma classe, um mtodo, uma funo, um texto ou um nmero. Qualquer tipo de dado, como int e string, por exemplo, tambm objeto e se comporta como objeto.

Isso quer dizer que qualquer coisa em Python pode ser passada como parmetro para uma funo ou mtodo, pois qualquer coisa um objeto, e tambm quer dizer que qualquer objeto pode conter atributos e mtodos (mas veremos isso mais adiante).

Vamos, por exemplo, utilizar o comando help passando como parmetro o nmero inteiro 1. 1 um objeto do tipo int (inteiro); quando passarmos 1 para a funo help teremos como resposta uma descrio detalhada a respeito da classe int e todos os seus mtodos. Levando em conta que 1 uma instncia da classe int, podemos ento utilizar qualquer mtodo de int em 1.

Veja o resultado:

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.

>>> help(1) Help on int object: class int(object) | int(x[, base]) -> integer | | Convert a string or number to an integer, if possible. A floating point | argument will be truncated towards zero (this does not include a string | representation of a floating point number!) When converting a string, use | the optional base. It is an error to supply a base when converting a | non-string. If base is zero, the proper base is guessed based on the | string content. If the argument is outside the integer range a | long object will be returned instead. | | Methods defined here: | | __abs__(...) | x.__abs__() <==> abs(x) : ( continua.....)

Perceba que aqui s mostramos uma pequena parte do retorno de help, pois a lista de mtodos muito grande. O mesmo resultado pode ser obtido utilizando a prpria classe int:
1. >>> help(int)

help exibe uma documentao muito detalhada, e s vezes queremos ver apenas uma listagem de mtodos disponveis em um certo objeto - para isso, utilizamos o comando dir.
Perceba que dir e help tambm so objetos, so funes que aqui chamaremos de comandos, apenas para diferenciar as funes da linguagem Python das funes de um programa especfico, criado por voc ou no. Tente executar help(dir) ou dir(help) e veja o resultado:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

{{ Desenvolvimento web com Python e web2py }}

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.

>>> dir(1) ['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'conjugate', 'denominator', 'imag', 'numerator', 'real']

Acima esto listados todos os mtodos disponveis na classe int que podem ser chamados a partir do objeto 1. Veja como invocar um mtodo a partir de um objeto:
1. >>> objeto = 234 #Criamos uma variavel(objeto) e atribuimos o valor inteiro 234 2. >>> objeto.__hex__() #O mtodo __hex__() da classe **int** converte para hexadecimal 3. '0xea'

Curiosidade, saiba mais sobre a filosofia Python


digite o seguinte cdigo no terminal interativo: 1. >>> import this

Tipos dinmicos
O Python efetua tipagem dinmica dos objetos, uma varivel no precisa possuir um tipo especfico de dados, e as variveis tambm no precisam ser declaradas. Considere uma varivel Python como sendo um espao em memria que pode receber referncia para objetos com valores de qualquer tipo. Portanto, so os valores que possuem tipo, e este tipo definido dinamicamente.
Podemos verificar qual o tipo de dado de um valor utilizando o comando type:

1. 2. 3. 4. 5. 6. 7. 8. 9.

>>>type(1) <type 'int'> >>>type(1.25) <type 'float'> >>>type('texto') <type 'str'> >>>variavel = 'Mensagem' >>>type(variavel) <type 'str'>

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

10

{{ Desenvolvimento web com Python e web2py }}

str (strings)
Python suporta o uso de dois tipos de string: ASCII e Unicode. ASCII so as strings usuais delimitadas por '...', "..." ou por """...""". Trs aspas delimitam strings com mltiplas linhas. Strings Unicode devem comear com uma letra u, seguida da string. Unicode pode ser convertido para ASCII e vice-versa. Por padro, o web2py utiliza UTF8 para strings.

Interpolao de variveis em strings


possvel interpolar o contedo de variveis em strings de diversas maneiras:
1. 2. 3. 4. 5. 6. >>> 'estamos no ano de ' + str(2010) estamos no ano de 2010 >>> 'estamos no ano de %s ' % (2010) estamos no ano de 2010 >>> 'estamos no ano de %(ano)s ' % dict(ano=2010) # recomendado estamos no ano de 2010

A ltima opo mais explcita, e causa menos erros. a maneira recomendada sempre que possvel.
A partir da verso 2.6, est disponvel outra maneira de interpolao, utilizando a funo format() 1. 2. 3. 4. 5. >>> 'Desenvolvimento web com {0} e {1}'.format('Python','web2py') 'Desenvolvimento web com Python e web2py' >>> 'Desenvolvimento web com {linguagem} e {framework}'\ ... .format(framework='web2py',linguagem='Python') 'Desenvolvimento web com Python e web2py'

Estruturas de dados
Listas
Listas so colees heterogneas de objetos, que podem ser de qualquer tipo, inclusive outras listas. As listas no Python so mutveis, podendo ser alteradas a qualquer momento. Elementos de uma lista podem ser acessados atravs de seu ndice.

Sintaxe
1. lista = [a, b, ..., z]

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

11

{{ Desenvolvimento web com Python e web2py }}

Operaes com listas


Listas so objetos iterveis, ordenados e indexveis. Veja os seguintes exemplos:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. >>> linguagens = ['Python','PHP','Ruby','Java','Lua'] #criando a lista >>> linguagens.append('VB') #Adicionando um item lista >>> for linguagem in linguagens: print linguagem ... Python PHP Ruby Java Lua VB >>> linguagens[-1] #o ltimo elemento da lista 'VB' >>> linguagens[0] #o primeiro elemento da lista 'Python' >>> linguagens[2:]#tudo do terceiro item em diante ['Ruby', 'Java', 'Lua', 'VB'] >>> linguagens[2:5]#do terceiro at o quinto elemento ['Ruby', 'Java', 'Lua'] >>> linguagens.remove('VB') #Removendo >>> linguagens.sort() #Ordenando >>> linguagens ['Java', 'Lua', 'PHP', 'Python', 'Ruby'] >>>

Tuplas
Tuplas so semelhantes s listas, porm so imutveis: no se pode acrescentar, apagar ou fazer atribuies aos itens. Sintaxe:
1. >>> minhatupla = (a, b, ..., z) # parnteses opcionais 2. >>> minhatupla = a, b, ..., z # o resultado o mesmo 3. >>> minhatuple = ( 1, ) # Tuplas com apenas um item terminam com uma vrgula

As tuplas so muito teis quando necessitamos garantir a integridade dos dados, ao criar entradas de configurao que no se alteram durante o programa, por exemplo. Listas podem ser convertidas em tuplas, e tuplas podem ser convertidas em listas:
1. >>> minhalista = list(minhatupla) 2. >>> minhatupla = tuple(minhalista)

Embora as tuplas possam conter elementos mutveis, no possvel fazer atribuies, pois isso modificaria a referncia ao objeto.
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

12

{{ Desenvolvimento web com Python e web2py }}


1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. >>> minhalista = [1,2] >>> minhatupla = (minhalista,4,[1,2],'Python') >>> minhatupla ([1, 2], 4, [1, 2], 'Python') >>> minhatupla[0].append(3) #adicionamos um item a minhalista >>> minhatupla ([1, 2, 3], 4, [1, 2], 'Python') >>> minhatupla[0] = [1,2,3,4] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment

As tuplas so mais eficientes do que as listas, pois consomem menos recursos e demandam menos operaes computacionais. Tuplas so muito utilizadas para empacotar e desempacotar valores:
1. 2. 3. 4. 5. 6. >>> a = 2, 3, 'hello' >>> x, y, z = a >>> print x 2 >>> print z hello

Dicionrios
Um dicionrio uma lista de associaes compostas por uma chave nica e estruturas correspondentes. Dicionrios so mutveis, tais como as listas. Os dados nos dicionrios so armazenados em uma estrutura chave:valor
1. >>> pessoa = {'nome':'Joo','idade':35,'altura':1.69}

Um dicionrio uma estrutura de dados que se parece com um banco de dados, e seus valores podem ser acessados atravs de sua chave.
1. 2. 3. 4. 5. >>> pessoa['nome'] 'Joo' >>> pessoa['idade'] 35 >>> Pessoa['Peso'] = 67

Podemos colocar dicionrios dentro de dicionrios:


1. 2. 3. 4. 5. 6. 7. 8. 9. >>> pessoas = {} >>> pessoas['Bruno'] = {'idade':27,'Cidade':'Cotia'} >>> pessoas['Claudia'] = {'idade':29,'Cidade':'Taubate'} >>> pessoas {'Claudia': {'idade': 29, 'Cidade': 'Taubate'}, 'Bruno': {'idade': 27, 'Cidade': 'Cotia'}} >>> pessoas['Claudia'] {'idade': 29, 'Cidade': 'Taubate'} >>> pessoas['Claudia']['idade'] 29

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

13

{{ Desenvolvimento web com Python e web2py }}

Dicionrios so iterveis, podemos percorrer seus elementos:


1. 2. 3. 4. 5. >>> for pessoa in pessoas: print pessoa +' '+pessoas[pessoa]['Cidade']\ ... +' '+str(pessoas[pessoa]['idade']) ... Claudia Taubate 29 Bruno Cotia 27

No caso acima o objeto pessoas um dicionrio, e possui dentro dele outros dois dicionrios identificados pelas chaves 'Bruno' e 'Claudia'. Esses dois dicionrios, por sua vez, tambm armazenam um dicionrio dentro de si, cada um com as chaves 'idade' e 'cidade'. Poderamos ir mais longe e incluir inmeros dicionrios aninhados. As chaves nos dicionrios podem ser dos tipos int, string ou qualquer objeto que implemente o mtodo __hash__. Valores podem ser de qualquer tipo, podemos ter diferentes tipos de chaves e valores em um nico dicionrio. Se os valores forem todos alfanumricos, o dicionrio pode ser declarado com a sintaxe alternativa:
1. 2. 3. 4. 5. >>> pessoas = dict(Bruno={'idade':27,'Cidade':'Cotia'},Claudia={'idade':29,'Cidade':'Taubate'}) >>> pessoas {'Claudia': {'idade': 29, 'Cidade': 'Taubate'}, 'Bruno': {'idade': 27, 'Cidade': 'Cotia'}} >>> pessoas['Claudia']['idade'] 29

Os mtodos mais utilizados em dicionrios so has_key, keys, values and items:


1. 2. 3. 4. 5. 6. >>> pessoas.keys() ['Claudia', 'Bruno'] >>> pessoas.values() [{'idade': 29, 'Cidade': 'Taubate'}, {'idade': 27, 'Cidade': 'Cotia'}] >>> pessoas.items() [('Claudia', {'idade': 29, 'Cidade': 'Taubate'}), ('Bruno', {'idade': 27, 'Cidade': 'Cotia'})]

O mtodo items produz uma lista de tuplas, cada uma contendo a chave e seu respectivo valor. Esta sada muito til para efetuar operaes como esta:
1. 2. 3. 4. 5. >>> for item in pessoas.items(): ... print item ... ('Claudia', {'idade': 29, 'Cidade': 'Taubate'}) ('Bruno', {'idade': 27, 'Cidade': 'Cotia'})

Itens de listas e dicionrios podem ser excludos com o comando del


1. >>> del pessoas['Bruno'] 2. >>> pessoas 3. {'Claudia': {'idade': 29, 'Cidade': 'Taubate'}}

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

14

{{ Desenvolvimento web com Python e web2py }}

Internamente, o Python usa o operador hash para converter objetos para int, e utiliza este valor inteiro para determinar onde armazenar o valor.

1. >>> hash("hello world") 2. -1500746465

Sobre endentao
Dentro da computao, Endentao (recuo, neologismo derivado da palavra em ingls indentation, tambm encontram-se as formas identao e indentao) um termo aplicado ao cdigo fonte de um programa para indicar que os elementos hierarquicamente dispostos tm o mesmo avano relativamente posio (x,0). Na maioria das linguagens a indentao tem um papel meramente esttico, tornando a leitura do cdigo fonte muito mais fcil (read-friendly), porm obrigatria em outras. Python, occam e Haskell, por exemplo, utilizam-se desse recurso tornando desnecessrio o uso de certos identificadores de blocos ("begin" e/ou "end"). Fonte:wikipedia

Python usa a endentao para delimitar blocos de cdigo. Um bloco inicia-se com uma linha terminada em dois pontos (:), e continua para todas as linhas que tenham uma endentao similar ou mais recuada. Por exemplo:
1. 2. 3. 4. 5. 6. 7. 8. >>> i = 0 >>> while i < 3: >>> print i >>> i = i + 1 >>> 0 1 2

comum utilizar 4 espaos para cada nvel de endentao. uma boa prtica no misturar espaos com tabulaes, pois pode gerar problemas.

Iterao de elementos
Em Python voc pode efetuar loops em objetos iterveis utilizando os comandos for...in e while:
1. 2. 3. 4. 5. 6. 7. 8. >>> lista = [0, 1, 'hello', 'python'] >>> for item in lista: ... print item ... 0 1 hello python

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

15

{{ Desenvolvimento web com Python e web2py }}

Duas funes que so bastante teis: xrange e a range


1. 2. 3. 4. 5. 6. 1. 2. 3. 4. 5. 6. >>> for i in xrange(3,6): ... print i ... 3 4 5 >>> for i in range(3): ... print i ... 1 2 3

Esta sintaxe equivalente ao seguinte cdigo C/C++/C#/Java: 1. for(int i=0; i<3; i=i+1) {print(i);)

Voc pode abortar um loop utilizando o comando break


1. 2. 3. 4. >>> for i in [1, 2, 3]: ... print i ... break 1

possvel ir para a prxima iterao, sem a necessidade de executar todo o cdigo definido no bloco, utilizando o comando continue
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. >>> for i in [1, 2, 3]: ... print i ... if i==2: ... continue ... print 'test' ... 1 test 2 3 test

while
while (enquanto) em Python funciona de maneira muito similar a outras linguagens. Este comando efetua a repetio indefinidas vezes, testando uma condio no final de cada iterao at que a condio seja igual a False
1. 2. 3. 4. 5. >>> while i < 10: ... i = i + 1 ... >>> print i 10

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

16

{{ Desenvolvimento web com Python e web2py }}

Expresses condicionais
O uso de condies em Python intuitivo:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. >>> for i in range(3): ... if i == 0: ... print 'Zero' ... elif i == 1: ... print 'Um' ... else: ... print 'Outro' ... Zero Um Outro

elif o mesmo que else if, e voc pode ter quantos elifs desejar, mas s permitido apenas um else sempre como ltima condio do bloco.

Funes
Funes so blocos de cdigo nomeados. Criadas para permitir a reutilizao de cdigo, as funes podem receber argumentos. Algumas funes j esto presentes no interpretador Python.
Exemplo de funo 1. >>> def nome_da_funcao(argumento1, argumento2): 2. ... bloco de cdigo 3. ... return <resultado>

O web2py segue o estilo de marcao determinado no PEP-8 , por isso ser comum ver funes nomeadas com o uso de 'underline', ex: nome_da_funcao. Porm, voc pode preferir utilizar outro estilo, como camelCasing ou PascalCasing na hora de criar as suas prprias funes.

Retorno de valores Se a funo retorna algum valor, como no caso de uma soma ou outro tipo de tratamento de dado, utilizado o comando return para especificar o que ser retornado.
1. 2. 3. 4. 5. >>> def soma(x,y): ... return x + Y ... >>> soma(1,2) 3

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

17

{{ Desenvolvimento web com Python e web2py }}

Uma nica funo poder retornar mais de um objeto, e uma funo pode receber argumentos nomeados:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. >>> def consulta_produto(id,desconto=False): ... if id: ... produto = id ... if desconto==False: ... return produto,'sem desconto' ... else: ... return produto,'com desconto' ... >>> consulta_produto(desconto=True,id=10) (10, 'com desconto')

lambda
Expresses lambda so funes que no possuem nome e que so criadas dinamicamente:
1. 2. 3. 4. 5. 6. 7. >>> def soma(a, b): ... return a+b ... >>> soma_alterada = lambda a: 5 + soma(a, 3) >>> soma_alterada(2) 10 >>>

A expresso lambda [a]:[b] pode ser lida como: uma funo que recebe o argumento a e retorna o valor b. Mesmo sendo uma funo sem nome, ela pode ser referenciada por uma varivel soma_alterada e desta maneira possvel invoc-la. lambda muito til para efetuao de refatoramento e sobrecarga (overloading) de mtodos e funes.

Executando cdigo pr-determinado


Diferente de C#, Java ou PHP, Python uma linguagem totalmente interpretada. Isso significa que Python tem a habilidade para executar blocos de cdigo armazenados em strings:
1. >>> a = "print 'web2py Brasil'" 2. >>> exec(a) 3. 'web2pyBrasil' 4.

Comentrios e docstrings
Existem duas maneiras para inserir um comentrio em Python. Para comentrios gerais no meio do bloco de cdigo, basta utilizar o caractere #
1. >>> def funcao(): # aqui definimos uma funo 2. ... # na linha abaixo retornamos o valor 3. ... return <valor>

Tambm podemos utilizar docstrings, que possuem duas funcionalidades. Docstring uma maneira de inserir comentrios, ou string multilinhas, mas tambm pode ser
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

18

{{ Desenvolvimento web com Python e web2py }}

utilizada para gerar documentao automaticamente. Docstrings so definidas com trs aspas simples ou duplas.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. >>> def funcao(): ... """ ... Aqui comea minha docstring, este texto servir ... como documentao que pode ser gerada por ferramentas como **epydoc** ... docstrings tambm so usadas por ferramentas de TDD como **doctests** ... geralmente explicam como utilizar a funo, ou incluem cdigo python ... >>> funcao() ... 'retorno da funcao' ... """ ... return 'retorno da funcao'

Voc pode acessar o texto da docstring de uma funo, ou at mesmo executar cdigo Python contido na docstring.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. >>> def funcao(): ... """ ... docstring da funcao ... essa funcao nao tem retorno ... """ ... return None ... >>> funcao() >>> funcao.__doc__ '\n docstring da funcao\n essa funcao nao tem retorno\n

'

O mesmo resultado obtido tambm com o uso do comando help(funcao).

Mdulos
Cada arquivo em Python chamado de mdulo. Mdulos so conjuntos de cdigos como funes, classes, mtodos, variveis etc. Vrios mdulos podem se comunicar atravs do comando import modulo. Vamos pegar o seguinte mdulo como exemplo:

contedo do arquivo modulox.py


1. def soma(a,b): 2. return a + b

Agora podemos utilizar a funo de soma definida em modulox.py em qualquer parte do nosso projeto importando mdulos
Existem dois modos principais para importar um mdulo:

Importando com alto acoplamento:


desta maneira as funes e variveis do modulox precisam ser acessadas mantendo-se o nome do mdulo como em modulox.soma()
1. >>> import modulox # aqui importamos o mdulo **modulox.py** 2. >>> print modulox.soma(3,6) # aqui invocamos a funo **soma** 3. 9

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

19

{{ Desenvolvimento web com Python e web2py }}

Importando diretamente:
desta forma todos os objetos definidos em modulox ficam diretamente disponveis para acesso dentro do programa atual, e ainda temos a opo de escolher quais objetos iremos importar.

Para importar todos os objetos utilizaremos *


1. >>> from modulox import * # todos os objetos definidos em modulox.py 2. >>> from modulox import soma # apenas a funo soma 3. >>> from modulox import soma as minhasoma # importar a funo soma e renomear

Em todos os casos acima, os objetos importados ficam diretamente acessveis:


1. 2. 3. 4. >>> print soma(3,6) 9 >>> print minhasoma(3,6) 9

List Comprehensions
Compreenso de listas uma construo que permite processar listas de uma maneira muito similar linguagem matemtica. A sintaxe [<expresso> for <varivel> in <lista> if <condicao>] onde: <varivel> in <lista> pode se repetir N vezes. e a <condio> opcional. Vamos utilizar a funo soma, por exemplo:
1. >>> print [modulox.soma(numero,5) for numero in range(10) if numero!=5] 2. [5, 6, 7, 8, 9, 11, 12, 13, 14]

No exemplo acima, executamos a funo soma para somarmos 5 a cada nmero da lista gerada pelo comando range(10) apenas se o numero for diferente de 5.

Referncias
[1] "www.python.org/dev/peps" [2] "http://www.python.org.br/wiki/InicieSe"

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

20

{{ Desenvolvimento web com Python e web2py }}

WSGI
Tambm pronunciado como uisgui, WSGI a especificao que determina os padres de acesso e comunicao entre servidores web e aplicaes escritas em Python. WSGI descrito em detalhes no PEP 333

WSGI no foi feito para desenvolvimento de aplicativos, mas sim para desenvolvimento de frameworks e webservers.

Exemplo de uma aplicao compatvel com WSGI:


1. def app(environ, start_response): 2. start_response('200 OK', [('Content-Type', 'text/plain')]) 3. from modulox import soma 4. resultado = soma(2,3) 5. yield 'Resultado da soma: %s' % resultado

Yield, em Python, usado nos generators. Generators so uma forma de gerar iterators. O yield faz com que a funo pare onde ele for chamado, e que na prxima vez em que for chamado, os valores sejam os mesmos da vez anterior.

Caso voc queira escrever seu prprio framework, ou desenvolver um webserver, aconselho a leitura do site oficial do projeto WSGI

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

21

{{ Desenvolvimento web com Python e web2py }}

O Padro MVC
O padro de MVC (Model-View-Controller) possibilita uma separao inteligente entre o modelo de dados (Model), a lgica da aplicao (Controller) e a interface de apresentao (View).

Modelos (model)
o local onde definimos e gerenciamos os modelos de dados da aplicao, efetuamos conexes com bancos de dados e definimos a modelagem das tabelas, constantes, variveis e configuraes de acesso global.

Controladores (controller)
So as aes da aplicao, onde definimos as regras de negcio e as validaes de tempo de execuo.O controller quem recebe a entrada de dados, invoca os objetos do modelo de dados, efetua as validaes e envia como resposta uma viso.

Viso (view)
As vises apresentam os dados do model, invocados e tratados pelo controller. Podem ser qualquer tipo de interface com usurios (pginas HTML, Feeds RSS etc) ou com outros sistemas (XML webservices, API REST etc).

Referncias
[1] "http://www.python.org/dev/peps" [2] "http://wsgi.org/wsgi"

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

22

{{ Desenvolvimento web com Python e web2py }}

Preparando o ambiente de desenvolvimento


O web2py possibilita que o desenvolvedor se dedique integralmente criao da aplicao, pois no demanda instalaes, nem configuraes complicadas: basta baixar o framework e comear a desenvolver. multiplataforma, ou seja, voc pode rod-lo no Windows ou no Mac OS, utilizando os executveis disponveis para download no site oficial http://www.web2py.com (para quem utiliza os sistemas operacionais citados, basta baixar e executar). Se voc estiver utilizando Linux, baixe a verso cdigo fonte. Se o seu Linux for o Ubuntu, pode ser que seja necessrio instalar a biblioteca python-tk, atravs da utilizao do seguinte comando:
1. sudo apt-get install python-tk

Faa download da verso cdigo fonte do web2py e descompacte-o, ento, dentro do diretrio web2py, abra um terminal e execute o comando:
1. python web2py.py

possvel rodar o web2py em um servidor com Apache, ou em qualquer outro servidor com suporte para WSGI, CGI/FASTCGI ou com funo de proxy. O web2py tambm pode se conectar a vrios tipos de bancos de dados, porm, como o framework j vem com um webserver prprio e com os pacotes necessrios para acesso ao SQLite, utilizaremos a configurao padro. Ao rodar o comando citado acima, a seguinte tela ser exibida:

Defina uma senha para acesso aplicao de administrao e clique em Start Server. Seu navegador abrir automaticamente, exibindo a aplicao welcome (aplicao modelo). Alm disso, temos a aplicao admin, uma interface de administrao para as outras aplicaes, e tambm a aplicao examples, que apresenta diversos exemplos de cdigo.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

23

{{ Desenvolvimento web com Python e web2py }}

A aplicao welcome:

Clique em [click here for admin...] e entre com a senha definida no passo anterior.

admin - A interface de administrao:


admin o nome da interface de administrao que o web2py fornece. uma aplicao como qualquer outra, porm com poderes de administrar os arquivos e bancos de dados das demais aplicaes.

Esta pgina exibe todas as aplicaes instaladas e permite que o administrador as gerencie.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

24

{{ Desenvolvimento web com Python e web2py }}

Atravs desta pgina de administrao voc pode executar as seguintes operaes: Install - Instalar uma nova aplicao em seu web2py. possvel instalar uma aplicao informando sua URL ou o caminho para um pacote w2p. Aplicativos w2p totalmente funcionais esto disponveis em http://web2py.com/appliances. uninstall - Desinstala uma aplicao. create - Cria uma nova aplicao
Quando voc cria uma nova aplicao, o web2py cria um clone da aplicao de modelo welcome, incluindo um arquivo de modelo em models/db.py que cria e efetua a conexo com um banco de dados SQLite, instancia e configura as classes de autenticao Auth, de criao de formulrios CRUD e de Servios (XML-RPC). Ele tambm cria um controller controllers/default.py que expe as aes index, download, user para gerenciamento de usurios, e call para chamada de servios.

package - Permite empacotar uma aplicao que voc desenvolveu e distribu-la no formato w2p. compile - Compila uma aplicao para a distribuio binria sem o cdigo fonte. errors - Exibe os tickets de erro gerados pela aplicao. clean up - Limpa todos os arquivos temporrios, sesses, tickets de erro e arquivos de cache de uma aplicao. EDIT - Abre a aplicao em modo de edio.

Criando sua primeira aplicao


Comece criando uma aplicao chamada myapp:

Aps voc clicar em [create], a aplicao ser criada como uma cpia da aplicao welcome.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

25

{{ Desenvolvimento web com Python e web2py }}

Para executar sua nova aplicao visite a seguinte URL: http://127.0.0.1:8000/myapp Voc ver uma cpia da aplicao welcome, clique em EDIT para entrar em modo de edio da aplicao:

A pgina de edio exibe o que existe dentro da aplicao. Toda aplicao web2py consiste em um certo conjunto de arquivos; os mais importantes esto nas seguintes categorias: [models] Modelos o local onde definimos e gerenciamos os modelos de dados da aplicao, efetuamos conexes com bancos de dados e definimos a modelagem das tabelas, constantes, variveis e configuraes de acesso global. [controllers] Controladores So as aes da aplicao. Aqui definimos as regras de negcio e as validaes de tempo de execuo; o controller quem recebe a entrada de dados, invoca os objetos do modelo de dados, efetua as validaes e envia como resposta uma viso. [views] Vises So as vises que serviro para apresentar os dados do model, invocados e tratados pelo controller. So criadas a partir de templates que podem responder contedo no formato HTML, RSS, XML e JSON, entre outros. [languages] Linguagens Local onde definimos arquivos de linguagem que permitem a internacionalizao das aplicaes.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

26

{{ Desenvolvimento web com Python e web2py }}

[static] Estticos Neste diretrio, inserimos arquivos que no necessitam de processamento, como estruturas estticas de layout, imagens, arquivos de estilo CSS e JavaScript. [modules] Mdulos - Aqui colocaremos bibliotecas e mdulos Python que no fazem parte do web2py, mas que podem ser importados e utilizados nas aplicaes.
Cada arquivo ou pasta exibido na interface administrativa, corresponde a um arquivo fsico localizado no diretrio da aplicao. Qualquer operao realizada na interface administrativa pode ser realizada atravs de comandos de terminal, e os arquivos podem ser editados em qualquer editor de textos ou IDE.

As aplicaes ainda possuem outros tipos de arquivo (bancos de dados, arquivos de sesso, tickets de erro etc.), mas estes arquivos no so listados na pgina de edio, pois no so criados ou gerenciados pelo desenvolvedor: eles so criados e modificados pela prpria aplicao.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

27

{{ Desenvolvimento web com Python e web2py }}

Camadas, mdulos e pacotes do web2py

A partir do zero
Vamos criar uma aplicao a partir do zero. Abra a pasta web2py/applications e dentro dela crie uma nova pasta chamada myappzero.

Dentro desta pasta criaremos os arquivos essenciais para que esta pasta se transforme em uma aplicao web2py. __init__.py Este arquivo informa ao interpretador que esta pasta um pacote Python e desta forma poder ser executado como aplicao web2py. Este arquivo nomeado com dois underlines, no incio e no final, __init__.py, e no possui contedo.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

28

{{ Desenvolvimento web com Python e web2py }}

ABOUT Este arquivo conter a descrio de sua aplicao. Ele um arquivo obrigatrio, apesar de ser permitido que fique em branco. Recomenda-se que seja preenchido pelo menos com as informaes bsicas: descrio da aplicao, verso e nome do autor. interessante informar, neste arquivo, alguma dependncia que a aplicao possa ter, e incluir instrues de instalao e configurao. LICENSE Este arquivo conter a declarao de licena para o software desenvolvido com web2py. A licena do web2py permite que a aplicao seja distribuda de forma comercial, desde que tenha seu prprio arquivo de licena. controllers Nesta pasta criaremos os arquivos que contero a lgica principal da aplicao. Em cada um destes arquivos criaremos as funes Python que chamaremos de aes, e cada ao ser mapeada para uma URL: http://servidor/aplicao/controller/ao/argumento1/argumento2 models Nesta pasta criaremos os modelos de dados e as configuraes globais. Os arquivos dentro de models sero executados em ordem alfabtica. views Nesta pasta criaremos os arquivos de layout e as vises para a apresentao dos dados. O contedo da pasta myappzero, passar a ser uma aplicao web2py.

Modelos (models)
Vamos comear pelos modelos. De acordo com a especificao do padro MVC, os modelos devem tratar apenas das estruturas e modelos de dados, porm o web2py d ao desenvolvedor a flexibilidade de escrever qualquer tipo de cdigo Python dentro do nvel dos modelos. O web2py l os arquivos de modelo em ordem alfabtica e executa todo cdigo contido nestes arquivos; instncia objetos e variveis de acesso global; executa funes; conecta, modela, verifica e cria tabelas no banco de dados. Para entender o ciclo de vida de uma aplicao web2py, crie um arquivo chamado modelo1.py dentro da pasta applications/myappzero/models:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

29

{{ Desenvolvimento web com Python e web2py }}

1. 2. 3. 4. 5. 6. 7.

# -*- coding: utf-8 -*print globals() print '_'*80 print 'inicio do ciclo de vida da aplicao web2py' print 'criando uma lista global' lista1 = ['modelo1','primeiro a ser executado'] print lista1

Quando inclumos o comando print em qualquer arquivo de uma aplicao web2py, esta informao enviada para o terminal onde o web2py est sendo executado. Este um recurso muito til para depurar a aplicao.

Abra o terminal de execuo do web2py e o deixe visvel; ao lado abra a janela do navegador e aponte para a URLhttp://127.0.0.1:8000/myappzero A sada de dados do modelo modelo1.py no terminal ser:

print globals() - Exibe todos os objetos que esto no escopo global do interpretador Python, incluindo os objetos carregados pelo prprio Python e tambm os objetos carregados pelo web2py. print '_'*80 - Apenas para dividir o contedo na tela, imprimimos 80 vezes o caractere underline exibimos algumas mensagens de status criamos um objeto do tipo lista contendo dois elementos; esta lista a partir de agora ficar no escopo global imprimimos o contedo da lista recm criada

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

30

{{ Desenvolvimento web com Python e web2py }}

O web2py mostrar a mensagem invalid controller, pois estamos chamando diretamente a aplicao, que neste momento apenas invocar a execuo dos modelos. Todos os arquivos da pasta models sero executados em ordem alfabtica e todos os objetos criados nestes arquivos sero instanciados na memria de escopo global. A memria poder ser acessada atravs dos controladores e at mesmo atravs das vises. Na janela de terminal onde o we2py est sendo executado, voc ver a sada dos comandos print que escrevemos nos controllers. Vamos agora nos certificar de que o web2py est mesmo respeitando a ordem alfabtica na execuo dos modelos e criar um novo arquivo, na pasta models, chamado modelo2.py
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. # -*- coding: utf-8 -*print '_'*80 print 'segundo modelo a ser executado pelo web2py' print 'criando outra lista global' lista2 = ['modelo2','segundo a ser executado'] print lista2 print 'importando o mdulo calendrio e imprimindo os meses' import calendar meses = [month for month in calendar.month_name] print meses

Atualize a tela do seu navegador e verifique a sada no terminal.

Nos modelos modelo1 e modelo2 criamos e instanciamos globalmente os objetos: lista1, lista2 e meses. Estes objetos esto agora disponveis para acessarmos atravs dos controladores e das views.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

31

{{ Desenvolvimento web com Python e web2py }}

Verifique a pasta raiz da aplicao e veja que no momento em que efetuamos o primeiro request ao servidor, o web2py agora criou automaticamente todos os arquivos que faltavam na aplicao.

Controladores (controllers)
Agora vamos criar um arquivo controlador. Um controlador o responsvel pela execuo de tarefas lgicas da aplicao, tratamento de dados e comunicao com as vises. Nos controladores criamos funes Python que chamamos de aes e cada ao poder ser mapeada para uma URL. As aes podem responder para uma ou mais vises, assim como as vises podero responder por uma ou mais aes. Os controladores tm acesso a todos os objetos que esto instanciados no escopo global da aplicao. Dentro da pasta controllers, crie um arquivo chamado controlador1.py.

Edite o arquivo controlador1.py e defina uma funo Python chamada acao1:


1. # -*- coding: utf-8 -*2. def acao1(): 3. print '_'*80 4. print 'Inicio da execuo da acao1 no controlador1' 5. lista1.append('acao1 inseriu um item a lista1') 6. print lista1 7. del lista2[1] 8. print 'acao1 excluiu um item de lista2' 9. print lista2 10. print 'acao1 ir se comunicar com a viso' 11. return dict(lista1=lista1,lista2=lista2,meses=meses)

Atualize a tela do seu navegador e verifique a sada no terminal, repare que a mensagem que aparece no navegador agora invalid view. Nosso ltimo passo ser criar a respectiva view.
O web2py expe apenas as funes que no recebem parmetros e que no comeam com_underline; ns chamaremos estas funes de aes. As funes que recebem parmetros e as comeadas por ''_underline" ficam disponveis apenas atravs de outras funes (aes), middlewares ou servios.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

32

{{ Desenvolvimento web com Python e web2py }}

Mapeamento de URLs
O mapeamento de URLs (dispatching) no web2py orientado a aes dos controladores. Cada ao de um controlador acessvel atravs de uma URL no seguinte formato: http://servidor:porta/aplicao/controlador/ao/argumentos?variveis http://servidor:porta Endereo IP e porta do servidor, em desenvolvimento 127.0.0.1:8080 /aplicao Pasta da aplicao web2py, ao ser chamada executa o cdigo dos modelos /controlador Mdulo controlador /ao Ao de um controlador, ao ser chamada executa o cdigo da funo correspondente, recebe os parmetros e variveis /argumentos Argumentos passados para o controlador so tratados como POST ?variveis Variveis so tratadas como GET (QueryString)

Para uma completa lista dos objetos de contexto visite a seguinte URL: http://127.0.0.1:8000/examples/simple_examples/status

Vises (views)
Vises so modelos HTML, RSS, JSON, XML ou qualquer outro tipo de modelo para apresentao das informaes. Por exemplo: tudo o que for apresentado ao navegador web faz parte da viso. No web2py, o template das vises marcado utilizando linguagem Python, e podemos fazer quase tudo que faramos em um programa Python ou Controller diretamente dentro da View. Apesar de ser recomendado deixar a lgica toda no Controller, s vezes muito til colocar um pouco de inteligncia nas Views. O padro para marcao segue os modelos abaixo, e os demais detalhes veremos no decorrer:

O cdigo da view no precisa seguir regras de endentaco do Python A marcao para escape feita dentro de {{ e }} Blocos de cdigo comeam nas linhas {{}} terminadas em : Blocos de cdigo terminam onde encontram a instruo {{pass}} Nos casos em que a construo do bloco for clara, no ser preciso usar o {{pass}}

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

33

{{ Desenvolvimento web com Python e web2py }}

Criando uma viso


As vises ficam no diretrio aplicao/views/. Podemos dizer ao controlador qual arquivo de viso ele ir invocar, porm, caso no faamos isso, o web2py determinar o uso de um arquivo de viso padro, que segue a mesma estrutura de nomenclatura e diretrio. Crie dentro da pasta myappzero/views uma pasta chamada controlador1. Quando uma ao do controlador1 for chamada, ela procurar dentro desta pasta uma view com o mesmo nome da ao, portanto: Crie o arquivo myappzero/views/controlador1/acao1.html:

Este arquivo conter o template para exibio dos dados da acao1, e poderemos executar qualquer cdigo Python dentro dele. Todos os objetos que foram retornados pelos modelos e controlador estaro disponveis para a viso:
1. <html> 2. <head></head> 3. <body> 4. {{print '_'*80}} 5. {{print 'Viso exibida no navegador'}} 6. {{=lista1}} 7. <br /> 8. {{=lista2}} 9. <br /> 10. <ul> 11. {{for mes in meses: 12. if mes: 13. }} 14. <li>{{=mes}}</li> 15. {{ pass 16. pass 17. }} 18. </ul> 19. </body> 20. </html> 21.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

34

{{ Desenvolvimento web com Python e web2py }}

Passagem de argumentos para a viso


O objeto request o transportador das variveis de requisio de uma aplicao web. Atravs do objeto request, podemos acessar trs propriedades principais: request.env (que armazena variveis de ambiente, sesso, cache etc), request.args e o request.vars.
1. <html> 2. <head></head> 3. <body> 4. {{print '_'*80}} 5. {{print 'Viso exibida no navegador'}} 6. {{print request.vars,request.args}} 7. {{=lista1}} 8. <br /> 9. {{=lista2}} 10. <br /> 11. <ul> 12. {{for mes in meses: 13. if mes: 14. }} 15. <li>{{=mes}}</li> 16. {{ pass 17. pass 18. }} 19. </ul> 20. {{print 'acessando argumentos'}} 21. {{=request.args[0]}} 22. <br /> 23. {{print 'acessando variveis'}} 24. {{=request.vars['variavel1']}} 25. </body> 26. </html>

Acesse o endereo: http://127.0.0.1:8000/myappzero/controlador1/acao1/argumento1?variavel1=valor1 Repare que estamos passando um primeiro argumento com o valor argumento1 e uma queryString com a chave variavel1 de valor1. A sada em seu navegador dever ser:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

35

{{ Desenvolvimento web com Python e web2py }}

ciclo de vida da aplicao


E a sada da janela de terminal dever ser:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. >, 'T': <gluon.languages.translator object at 0xceeee6c>, 'IS_IN_SET': <class 'gluon.validators.IS_IN_SET'>, 'IS_UPLOAD_FILENAME': <class 'gluon.validators.IS_UPLOAD_FILENAME'>, 'IS_DECIMAL_IN_RANGE': <class 'gluon.validators.IS_DECIMAL_IN_RANGE'>} ____________________________________________________________________ inicio do ciclo de vida da aplicao web2py criando uma lista global ['modelo1', 'primeiro a ser executado'] ____________________________________________________________________ segundo modelo a ser executado pelo web2py criando outra lista global ['modelo2', 'segundo a ser executado'] importando o mdulo calendrio e imprimindo os meses ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] ____________________________________________________________________ Inicio da execuo da acao1 no controlador1 ['modelo1', 'primeiro a ser executado', 'acao1 inseriu um item a lista1'] acao1 excluiu um item de lista2 ['modelo2'] acao1 ir se comunicar com a viso ____________________________________________________________________ Viso exibida no navegador <Storage {'variavel1': 'valor1'}> ['argumento1'] acessando argumentos acessando variveis

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

36

{{ Desenvolvimento web com Python e web2py }}

A camada de acesso a dados - DAL


O web2py possui uma camada de abstrao de banco de dados (DAL), que uma API que mapeia objetos Python em objetos de banco de dados como queries, tabelas e registros. A DAL gera cdigos SQL dinamicamente, em tempo real, utilizando sempre o dialeto SQL referente ao banco de dados em uso. Dessa forma, voc no precisa escrever cdigo SQL ou aprender comandos SQL de um banco de dados especfico, e sua aplicao ser portvel para diferentes bancos de dados. Atualmente, os bancos de dados suportados so: SQLite (que j vem com Python e com web2py), PostrgreSQL, MySQL, Oracle, MSSQL, FireBird, DB2, Informix e Ingres. O web2py tambm capaz de se conectar ao Google BigTable no Google App Engine (GAE). O framework define as seguintes classes para construir a DAL: DAL representa a conexo com o banco de dados
1. db = DAL('sqlite://storage.db')

O cdigo acima define uma referncia db para uma instncia da classe DAL, mapeada para um banco de dados do tipo sqlite com o nome storage.db, por padro armazenado na pasta databases. Table representa uma tabela no banco de dados, voc no pode instanciar Table diretamente: para isso usamos o mtodo DAL.define_table
1. db.define_table('minhatabela', Field('meucampo'))

O cdigo acima define uma tabela minhatabela, contendo apenas um campo meucampo. O web2py se encarrega de criar e executar o cdigo SQL responsvel pela criao desta tabela. O objeto db agora possui uma propriedade chamada minhatabela e o acesso feito com db.minhatabela. Os mtodos mais importantes da classe Table so: .insert, .truncate, .drop. Ex:
1. db.minhatabela.truncate()

Field representa um campo da tabela, ele pode ser instanciado ou passado como argumento para o mtodo DAL.define_table
1. db.define_table('minhatabela', 2. Field('meucampo', 'string', notnull=True, required=True,\ 3. requires=IS_NOT_EMPTY(), default='Ol Mundo'), 4. )

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

37

{{ Desenvolvimento web com Python e web2py }}

No exemplo anterior, Field recebe vrios argumentos que definem as propriedades deste campo na tabela. Este cdigo pode ser traduzido para o SQL CREATE TABLE minhatabela(meucampo varchar(255) not null default 'Ol Mundo'
O web2py possui uma srie de validadores. Alguns agem no nvel do banco de dados alterando assim a clusula SQL, como o caso no validador notnull=True, que se transforma em not null no SQL. Outros validadores, como o required=True, atuam no nvel da DAL definindo, por exemplo, que requerida a passagem de um valor para ser inserido neste campo. J outros, como o IS_NOT_EMPTY, funcionam no nvel do formulrio, desta forma, quando criamos um formulrio, este form ser validado garantindo que este campo no seja vazio.

A definio de validadores pode ser feita separadamente da definio da tabela, e esta uma prtica recomendada:
1. 2. 3. 4. 5. 6. 7. 8. db.define_table('minhatabela', Field('meucampo', 'string'), ) db.minhatabela.notnull=True db.minhatabela.required=True db.minhatabela.requires=IS_NOT_EMPTY() db.minhatabela.default='Ol Mundo'

DAL Rows o objeto retornado por um select, considere-o como uma lista de registros.
1. registros = db(db.minhatabela.meucampo!=None).select()

O mtodo select executa a clusula SELECT do SQL, utilizando as condies informadas em db(). Este mesmo cdigo em ANSI SQL ficaria: **SELECT * FROM minhatabela where meucampo is not null** Row contm campos com valores:
1. for registro in registros: 2. print registro.meucampo

Query um objeto que representa a clusula SQL where


1. minhaquery = (db.minhatabela.meucampo == 'Teste')

Este cdigo poderia ser traduzido para o fragmento minhatabela where meu campo = 'Teste', e esta query pr-definida poder ser aplicada ao objeto Set.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

38

{{ Desenvolvimento web com Python e web2py }}

Set um objeto que representa um conjunto de registros.


Seus mtodos mais importantes so count, select, update e delete. Por exemplo:

1. 2. 3. 4. 5. 6. 7. 8.

# definir o conjunto de registros ' SELECT * FROM minhatabela where meucampo = 'Teste' conjunto = db(minhaquery) # executar o select acima e popula o objeto registros registros = conjunto.select() # alterar os registros 'UPDATE minhatabela set meucampo = 'Teste2' where meucampo = 'Teste' conjunto.update(meucampo='Teste2') # deletar os registros 'DELETE FROM minhatabela where meucampo = 'Teste' conjunto.delete()

Expressions so usadas para representar, por exemplo, as expresses orderby ou groupby:

1. minhaordem = db.minhatabela.meucampo.upper() | db.minhatabela.id 2. db().select(db.minhatabela.ALL, orderby=minhaordem)

Representao de registros
Este argumento opcional, porm, muito til para a criao dos formulrios, pois esta representao ser utilizada para popular os drop-downs de referncia. Exemplo:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. db.define_table('pessoa', Field('nome'), format='%(name)s', ) # ou db.define_table('pessoa', Field('nome'), format='%(name)s %(id)s', )

# ou um pouco mais complexo


db.define_table('pessoa', Field('nome'), format=lambda r: r.nome or 'annimo', )

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

39

{{ Desenvolvimento web com Python e web2py }}

Nos trs casos acima, estamos definindo qual ser o padro de representao desta tabela, quando ela for referenciada em um drop-down. Ao invs de utilizar o campo id, o web2py usar a representao definida em format.

Interagindo com a DAL


possvel utilizar a DAL atravs do console; abra um terminal e digite:
1. python web2py.py -S welcome

O -S indica que o web2py ser iniciado no modo Shell welcome o nome da aplicao que iremos iniciar Ser exibido o console interativo do Python, porm, o ambiente web2py estar carregado na memria e a aplicao welcome ser instanciada. Como estamos no modo de console, precisamos importar manualmente o que iremos utilizar. Importe todo o contedo do pacote gluon:
1. >>> from gluon import *

Vamos criar e conectar com um banco de dados SQLite, utilizando a DAL:


1. >>> banco = DAL('sqlite://meubanco.db') 2. >>> banco.tables 3. []

Vamos criar uma tabela chamada carros, contendo os campos marca e modelo:
1. >>> banco.define_table('carros',Field('marca'),Field('modelo'))

Voc ver o cdigo SQL gerado pela DAL.


1. 2. 3. 4. 5. 6. 7. <Table {'ALL': <gluon.sql.SQLALL object at 0xa28c50c>, '_sequence_name': None, '_referenced_by': [], 'fields': ['id', 'marca', 'modelo'], '_db': <SQLDB {'_connection': <sqlite3.Connection object at 0xa1d8220>, '_lastsql': 'CREATE TABLE carros(\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n marca CHAR(512),\n modelo CHAR(512)\n ... .

Para listar as tabelas existentes em banco, execute:


1. >>> banco.tables 2. ['carros']

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

40

{{ Desenvolvimento web com Python e web2py }}

Para listar os campos da tabela carros, execute:


1. >>> banco.carros.fields 2. ['id', 'marca', 'modelo']

Insert, Select, Update, Delete


Inserindo registros Para inserir registros no banco de dados, usamos o mtodo insert da classe Table:
1. 2. 3. 4. >>> banco.carros.insert(marca='GM',modelo='Corsa') 1 >>> banco.carros.insert(marca='AUDI',modelo='A4') 2

Apesar de o mtodo insert retornar o id do registro que foi criado, este registro est apenas na memria e ainda no foi inserido no banco de dados fsico. Para executar a insero, precisamos explicitamente executar o mtodo commit e caso queiramos desfazer esta ao, utilizamos o mtodo rollback.
1. >>> banco.commit() # dados inseridos no banco SQLite

Voc pode inserir vrios registros ao mesmo tempo, utilizando o mtodo bulk_insert:
1. >>> novoscarros = [{'modelo': 'Corolla', 'marca': 'Toyota'}, \ 2. {'modelo': 'Fusca', 'marca': 'Volks'}, \ 3. {'modelo': 'Clio', 'marca': 'Renault'}] 4. >>> banco.carros.bulk_insert(*[ 5. {'marca':carro['marca'], 6. 'modelo':carro['modelo']} for carro in novoscarros]) 7. [3, 4, 5]


[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

41

{{ Desenvolvimento web com Python e web2py }}

Consultando os registros Existem duas formas de consultar todos os registros de uma tabela **SELECT * FROM **

Utilizando base.tabela.ALL
1. 2. 3. 4. 5. 6. 7. 8. 9. >>> registros = banco().select(banco.carros.ALL) >>> for registro in registros: ... print registro.marca,registro.modelo ... GM Corsa AUDI A4 Toyota Corolla Volks Fusca Renault Clio

O Cdigo SQL gerado pelo comando acima :


1. >>> banco._lastsql 2. 'SELECT carros.id, carros.marca, carros.modelo FROM carros;'


DAL._lastsql retorna o ltimo comando SQL executado pela DAL

Utilizando uma query


1. >>> registros = banco(banco.carros.id>0).select()

Deste modo, o operador id>0 poderia ser substitudo, utilizando os operadores (==, !=, <, >, <=, >=, like, belongs). Neste caso, o comando SQL seria: 'SELECT carros.id, carros.marca, carros.modelo FROM carros WHERE carros.id>0;'

Query

Para facilitar, voc pode armazenar a referncia para uma tabela em uma varivel.
1. >>> carros = banco.carros

Voc tambm pode armazenar a referncia para um campo em uma varivel:


1. >>> marca = carros.marca

Voc pode tambm definir uma query utilizando os operadores (==, !=, <, >, <=, >=, like, belongs) e armazenar esta query em uma varivel:
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

42

{{ Desenvolvimento web com Python e web2py }}

1. >>> query = marca!='Toyota'

Quando voc invoca o banco de dados com uma query, voc define um conjunto de registros, que tambm pode ser armazenado em uma varivel:
1. >>> conjunto = banco(query)

O comando anterior apenas define o conjunto de dados que ser retornado, porm, ainda no executa a query no banco de dados. Para executar esta query, necessrio chamar explicitamente:
1. 2. 3. 4. 5. 6. 7. 8. >>> registros = conjunto.select() >>> for registro in registros: ... print registro.marca,registro.modelo ... GM Corsa AUDI A4 Volks Fusca Renault Clio

O cdigo SQL que foi executado acima : "SELECT carros.id, carros.marca, carros.modelo FROM carros WHERE carros.marca<>'Toyota';"

Atalhos

A DAL suporta vrios tipos de atalho, em particular:


1. >>> meuregistro = banco.carros[id]

Seria o mesmo que:


1. >>> meuregistro = banco(banco.carros.id==1).select().first()

Outros atalhos funcionais so:


1. >>> registro = banco.carros(1) 2. >>> registro = banco.carros(banco.carros.id==1) 3. >>> registro = banco.carros(1,marca='GM')

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

43

{{ Desenvolvimento web com Python e web2py }}

Ordenao

Voc pode consultar os registros ordenados por marca:


1. 2. 3. 4. 5. 6. 7. 8. >>> for registro in banco().select(banco.carros.ALL, orderby=banco.carros.marca): ... print registro.marca,registro.modelo ... AUDI A4 GM Corsa Renault Clio Toyota Corolla Volks Fusca

Query mltipla
Podemos utilizar mais de um argumento como filtro de uma query. Para isso, podemos utilizar | (ou) e & (e)
1. 2. 3. 4. >>> for registro in banco((banco.carros.marca=='Toyota') | (banco.carros.modelo=='Clio')).select(): ... print registro.marca,registro.modelo... Toyota Corolla Renault Clio

Contagem de registros

Para contar a quantidade de registros em um conjunto, utilizamos o mtodo count():


1. >>> banco(banco.carros.id>0).count() 2. 5

Alterao de registros
Para alterar um registro existente no banco de dados, podemos usar:
1. 2. 3. 4. 5. 6. 7. 8. >>> carro = banco.carros[2] >>> carro.marca 'AUDI' >>> carro.modelo 'A4' >>> carro.modelo = 'A3' >>> carro.modelo 'A3'

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

44

{{ Desenvolvimento web com Python e web2py }}

Ou ento, podemos atualizar vrios registros de uma nica vez:


1. >>> carros = banco().select(banco.carros.ALL) 2. >>> for carro in carros: 3. ... carro.update(marca='FIAT')

Podemos tambm excluir os registros:


1. >>> banco(banco.carros.id>0).delete() 2. 5

Tipos de dados

A DAL suporta os seguintes tipos de dados:


Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name, Field(name,

'string') 'text') 'password') 'blob') 'upload') 'boolean') 'integer') 'double') 'time') 'date') 'datetime') db.referenced_table) # reference field list:string)

Atributos

Cada campo pode receber os seguintes atributos de acordo com o seu tipo de dado:

length (apenas para o tipo string, padro 32) default (padro None) required (padro False) notnull (padro False) unique (padro False) requires (um validador ou uma lista de validadores para os formulrios) comment (comentrios para formulrios) widget (para formulrios) represent (para formulrios) readable (determina se o campo visvel no formulrio, padro True) writable (determina se o campo altervel no formulrio, padro True) update (valor padro caso o registro seja atualizado)
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

45

{{ Desenvolvimento web com Python e web2py }}

uploadfield (para criao de um campo BLOB para upload, padro None) authorize (para autenticar em caso de download protegido) autodelete (padro False, caso True, apaga a imagem assim que sua referncia no banco for apagada) label (rtulos para os formulrios)

Migraes

Alterar a lista de campos ou os tipos dos campos em um modelo provoca uma migrao automtica, ou seja, o web2py gera cdigo SQL automaticamente para alterar a tabela de acordo com as mudanas. Se a tabela no existir, ela criada. Aes de migrao so registradas no arquivo Sql.log, acessvel atravs da interface administrativa. A migrao pode ser desligada por tabela em uma base de dados, passando o parmetro migrate = False no mtodo define_table.

Validadores

Validadores so classes usadas para validar campos de entrada em formulrios (incluindo os gerados atravs do banco de dados). Exemplo de uso de um validador na criao de um formulrio.
1. INPUT(_name='marca', requires=IS_NOT_EMPTY(error_message='Voc deve informar a marca!'))

Aqui um exemplo de uso de validador na base de dados:


1. banco.define_table('carros', Field('marca')) 2. banco.carros.marca.requires = IS_NOT_EMPTY()

Os validadores sempre so atribudos atravs do atributo requires da classe Field. Um campo pode ter um ou mais validadores. Mltiplos validadores so formados com uma lista
1. bancos.carros.marca.requires = [IS_NOT_EMPTY(), 2. IS_NOT_IN_DB(banco, 'carros.marca')]

Os validadores so invocados atravs da funo accepts em um FORM ou qualquer outro HTML helper que contenha um FORM. So invocados na exata ordem em que so listados.

Os validadores de formulrio

IS_ALPHANUMERIC Este validador checa se um campo contm um caractere dentro do range a-z, A-Z ou 0-9

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

46

{{ Desenvolvimento web com Python e web2py }}

IS_DATE Este validador checa se o campo contm uma data vlida, de acordo com o formato especificado
1. 2. requires = IS_DATE(format='%Y-%m-%d', 3. error_message='O formato deve ser AAAA-MM-DD')

IS_DATE_IN_RANGE() Funciona da mesma maneira que o IS_DATE, mas permite especificar um range de datas
1. requires = IS_DATE_IN_RANGE(format='%Y-%m-%d', 2. minimum=datetime.date(2008,1,1), 3. maximum=datetime.date(2009,12,31), 4. error_message='O formato deve ser AAAA-MM-DD' 5. )

IS_IN_SET Checa se o valor est contido em um conjunto (set):


1. requires = IS_IN_SET(['a', 'b', 'c'], 2. zero='escolha um valor', 3. error_message='o valor deve ser a, b ou c' 4. )

IS_LENGHT Verifica se o valor respeita o tamanho mnimo e mximo especificados. Os argumentos so: maxsize: O tamanho mximo permitido minsize: O tamanho mnimo permitido Exemplo: checa se o texto menor do que 10 caracteres:
1. INPUT(_type='text', _name='marca', requires=IS_LENGHT(9))

Verificando se a senha maior do que 5 caracteres:


1. INPUT(_type='password', _name='senha', requires=IS_LENGHT(minsize=6) )

IS_LOWER Este validador nunca retorna um erro, ele apenas converte o valor inserido para texto em minsculo.
1. requires = IS_LOWER()

IS_NOT_EMPTY Verifica se o valor do campo no est vazio.


1. requires = IS_NOT_EMPTY(error_message='No pode ser vazio')

IS_URL Verifica se o valor respeita a sintaxe de uma URL vlida.


[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

47

{{ Desenvolvimento web com Python e web2py }}


1. 2. 3. 4. 5. 6. 7. requires requires requires requires requires = = = = = IS_URL() IS_URL(mode='generic') IS_URL(allowed_schemes=['https']) IS_URL(prepend_scheme='https') IS_URL(mode='generic', allowed_schemes=['ftps', 'https'], prepend_scheme='https')

IS_IMAGE Em um campo de upload checa se o formato do arquivo uma imagem vlida. Podemos tambm especificar as dimenses mnima e mxima para o arquivo.
1. requires = IS_IMAGE(extensions=('jpeg', 'png'), maxsize(200, 200), minsize(50, 50))

IS_EMPTY_OR Se voc precisar que um campo aceite um valor vazio e ainda assim quiser efetuar outras validaes, por exemplo, em um campo que tem que ser uma data ou estar vazio:
1. requires = IS_EMPTY_OR(IS_DATE())

Os validadores de banco de dados


IS_NOT_IN_DB Considere o seguinte exemplo:


1. banco.define_table('pessoa', Field('nome')) 2. banco.pessoa.nome.requires = IS_NOT_IN_DB(banco, 'pessoa.nome')

Quando voc tentar inserir uma nova pessoa, ser validado se o nome j no existe no banco de dados banco, no campo pessoa.nome. Como os outros validadores, esta checagem feita no nvel do formulrio, portanto, aconselhvel utilizar sempre em conjunto com o validador unique que atua no banco de dados.
1. banco.define_table('pessoa', Field('nome', unique=True)) 2. banco.pessoa.nome.requires = IS_NOT_IN_DB(banco, 'pessoa.nome')

IS_IN_DB o IS_IN_DB funciona da mesma forma que o anterior, porm checa se o valor existe na tabela. notnull O validador notnull atua na camada do banco de dados, e traduzido para o cdigo SQL NOT NULL, no permitindo que o campo referido seja de valor nulo.
1. banco.define_table('pessoa', Field('nome', notnull=True)) 2. banco.pessoa.nome.requires = IS_NOT_IN_DB(banco, 'pessoa.nome')

lenght lenght define o tamanho de um campo do tipo texto:


1. banco.define_table('pessoa', Field('nome', lenght=55)) 2. banco.pessoa.nome.requires = IS_NOT_IN_DB(banco, 'pessoa.nome')

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

48

{{ Desenvolvimento web com Python e web2py }}

default default define o valor padro para o campo quando um valor no for definido:
1. banco.define_table('pessoa', Field('nome', default='annimo')) 2. banco.pessoa.nome.requires = IS_NOT_IN_DB(banco, 'pessoa.nome') widgets

Auto complete widget


Existem duas maneiras para utilizar o widget autocomplete, para autocompletar um campo que recebe uma lista para autocompletar ou a referncia de um campo contendo estes valores, ou para autocompletar um campo referenciado. O primeiro caso fcil: Defina no modelo
1. db.define_table('marcas', Field('marca')) 2. 3. db.define_table('carros', 4. Field('marca'), 5. Field('modelo'), 6. ) 7. 8. db.carros.marca.widget = SQLFORM.widgets.autocomplete( 9. request, db.marcas.marca, limitby=(0,5), min_length=2) 10.

limitby instrui o widget a mostrar no mais do que cinco sugestes por vez, e minlength define que deve ser digitado um nmero mnimo de caracteres para que a consulta Ajax seja executada. E no controller:
1. def index(): 2. form=SQLFORM(db.carros) 3. return dict(form=form)


Resultado:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

49

{{ Desenvolvimento web com Python e web2py }}

Outra forma definindo a gravao do id ao invs do texto:


1. db.define_table('marcas', Field('marca')) 2. 3. db.define_table('carros', 4. Field('marca'), 5. Field('modelo'), 6. ) 7. 8. db.carros.marca.widget = SQLFORM.widgets.autocomplete( 9. request, db.marcas.marca, id_field=db.marcas.id) 10.

Appadmin Para cada aplicao criada, o web2py prov um controlador chamado appadmin. Este controlador tem como objetivo auxiliar na administrao dos bancos de dados da aplicao. O controlador appdamin acessvel atravs da URL: http://127.0.0.1:8000/<suaapp>/appadmin/index Atravs deste controlador possvel: Visualizar a lista de tabelas definidas Executar queries da DAL Executar operaes CRUD nos registros do banco de dados (Inserir, Selecionar, Atualizar, Apagar) Exportar o contedo de uma tabela Importar contedo para uma tabela Lista de bancos de dados e tabelas definidas

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

50

{{ Desenvolvimento web com Python e web2py }}

Executando queries DAL

Inserindo um novo registro

Importao e exportao de registros

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

51

{{ Desenvolvimento web com Python e web2py }}

Log SQL
A aplicao admin armazena o log de todo o cdigo SQL executado pela DAL. http://127.0.0.1:8000/admin/default/peek/<suaapp>/databases/sql.log
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. timestamp: 2010-08-14T18:12:01.902993 CREATE TABLE auth_event( id INTEGER PRIMARY KEY AUTOINCREMENT, time_stamp TIMESTAMP, client_ip CHAR(512), user_id INTEGER REFERENCES auth_user(id) ON DELETE CASCADE, origin CHAR(512), description TEXT ); success! timestamp: 2010-08-14T18:12:01.913395 CREATE TABLE marcas( id INTEGER PRIMARY KEY AUTOINCREMENT, marca CHAR(512) NOT NULL UNIQUE ); success!

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

52

{{ Desenvolvimento web com Python e web2py }}

Mo na Massa - Viso Geral


O Projeto

Nosso cliente a lojadecarro.com e precisamos desenvolver um novo site para ele. Este site tem como objetivo exibir uma vitrine dos carros disponveis na loja e possibilitar que o cliente entre em contato demonstrando interesse de compra por algum veculo. Nosso cliente deseja uma interface para incluir, alterar e remover veculos. E quer tambm ter a possibilidade de inserir uma foto para cada veculo. Os veculos sero divididos nas categorias Novos e Usados, e temos a preocupao de tentar utilizar URLs simplificadas para otimizar as buscas. Por falar em busca, nosso cliente viu um site com uma busca que completa o texto do resultado conforme a digitao, e agora ele deseja uma busca igual para o seu site (com Ajax).

Loja de Carro

Requisitos Vendedor Incluir um novo veculo Alterar um veculo existente Remover um veculo Consultar compradores Consultar mensagens enviadas pelo site Comprador Pesquisar um veculo Visualizar detalhes do veculo Informar interesse de compra por um veculo Entrar em contato com a loja A aplicao Na interface administrativa do web2py crie uma nova aplicao chamada lojadecarro. Vamos utilizar a aplicao de modelo do web2py como base para este desenvolvimento. Layout O cliente tambm forneceu uma idia de como ele deseja que seja o layout da aplicao, desta forma, ficar mais fcil entender os requisitos.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

53

{{ Desenvolvimento web com Python e web2py }}

Pgina Home:

Pgina de detalhes


[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

54

{{ Desenvolvimento web com Python e web2py }}

Pgina de carros Usados/Novos

Pgina de administrao de carros

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

55

{{ Desenvolvimento web com Python e web2py }}

Modelagem do banco de dados


Com base na especificao e no layout, vamos comear pela modelagem das tabelas do nosso banco de dados: Primeiro, na interface administrativa da aplicao lojadecarro, delete o modelo existente db.py. Vamos fazer desde o incio.
Lembre-se que o web2py executa os modelos em ordem alfabtica, por este motivo sempre que temos cdigo que precisa ser executado no incio do ciclo de vida da aplicao, recomendada a criao de arquivos de modelo nomeados com nmeros de 0 a 10.

Crie um arquivo de modelo chamado 0, o web2py automaticamente criar um arquivo 0.py. Como este arquivo ser o primeiro a ser executado pela aplicao, vamos definir o banco de dados e algumas configuraes globais.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. arquivo 0.py # coding: utf8 db = DAL('sqlite://storage.sqlite') e_m = { 'empty':'Este campo obrigatrio', 'in_db':'Este registro j existe no banco de dados', 'not_in_db':'Este registro no existe no banco de dados', 'email':'Voc precisa inserir um e-mail vlido', 'image':'O arquivo precisa ser uma imagem vlida', 'not_in_set':'Voc precisa escolher um valor vlido', 'not_in_range':'Digite um nmero entre %(min)s e %(max)s', } config = dict(nmsite='Loja de Carro',dscsite='S os melhores carros') estados = ('Novo','Usado') cores = ('Azul','Amarelo','Verde','Vermelho','Prata','Branco','Preto','Vinho')

Em 0.py criamos a conexo com o banco de dados atravs da classe DAL e referenciamos por um objeto que chamamos de db. Criamos um dicionrio e_message, contendo mensagens de validao que usaremos nos formulrios da aplicao, e um dicionrio config, contendo o nome e a descrio da loja. Tambm definimos dois sets estados e cores para utilizar na validao dos formulrios.
Podemos utilizar o dicionrio config para armazenar qualquer tipo de configurao global da aplicao.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

56

{{ Desenvolvimento web com Python e web2py }}

Agora crie um novo arquivo de modelo chamado carros, o web2py ir criar um arquivo carros.py e redirecionar para a tela de edio do modelo. Neste modelo vamos definir todas as tabelas e validaes necessrias para a aplicao. Na hora de definir objetos e tabelas no arquivo de modelo, devemos sempre lembrar que Python uma linguagem interpretativa, ou seja, os comandos so executados respeitando-se a ordem em que foram definidos no cdigo.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. arquivo carros.py # coding: utf8 # criamos um validador pr definido notempty=IS_NOT_EMPTY(error_message=e_m['empty'])

# definio da tabela de marcas db.define_table('marca', Field('nome', unique=True, notnull=True), format='%(nome)s') # validadores da tabela de marcas db.marca.nome.requires=[notempty, IS_NOT_IN_DB(db, 'marca.nome', error_message=e_m['in_db'])]

# definio da tabela de carros db.define_table('carro', Field('marca', db.marca, notnull=True), Field('modelo', notnull=True), Field('ano', 'integer', notnull=True), Field('cor', notnull=True), Field('valor', 'double'), Field('itens', 'list:string'), Field('estado', notnull=True), Field('desc', 'text'), Field('foto', 'upload'), format='%(modelo)s - %(ano)s - %(estado)s' ) # validao da tabela carro db.carro.marca.requires=IS_IN_DB(db, 'marca.id','marca.nome', error_message=e_m['not_in_db']) db.carro.modelo.requires=notempty db.carro.ano.requires=[notempty, IS_INT_IN_RANGE(request.now.year20,request.now.year+2, error_message=e_m['not_in_range'])] db.carro.cor.requires=IS_IN_SET(cores) db.carro.itens.requires=IS_IN_SET(('Alarme','Trava','Som', 'Ar'),multiple=True, error_message=e_m['not_in_set']) db.carro.estado.requires=IS_IN_SET(estados,error_message=e_m['not_in_set']) db.carro.foto.requires=IS_EMPTY_OR(IS_IMAGE(extensions=('jpeg', 'png', '.gif'), error_message=e_m['image']))

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

57

{{ Desenvolvimento web com Python e web2py }}


47. # definio da tabela de compradores 48. db.define_table('comprador', 49. Field('id_carro', db.carro), 50. Field('nome'), 51. Field('email'), 52. Field('telefone'), 53. Field('financiar','boolean'), 54. Field('troca','boolean'), 55. Field('data', 'datetime', default=request.now) 56. ) # validao da tabela de compradores db.comprador.nome.requires=notempty db.comprador.email.requires=IS_EMAIL(error_message=e_m['email']) db.comprador.telefone.requires=notempty

Neste ponto j ser possvel, atravs do appadmin, inserir alguns registros no banco de dados. Insira algumas marcas como: Toyota','FIAT','GM','Volks','Ferrari','Smart'.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

58

{{ Desenvolvimento web com Python e web2py }}

Insira tambm cerca de dois registros de veculos na tabela de carros.

Exercicio: Analisando a definio de layout, os requisitos e o modelo de dados. Forme uma dupla e desenvolva o restante da aplicao Loja de Carro. Com a ajuda do instrutor crie os controllers e as views para cada uma das pginas apresentadas no layout. No se preocupe com design, layout e as barras laterais da aplicao, desenvolva apenas o contedo principal.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

59

{{ Desenvolvimento web com Python e web2py }}

Mapeamento de URLs
Controladores so a porta de entrada de uma aplicao web2py. Quando um usurio efetua uma requisio (request) no navegador, o web2py ir mapear esta requisio de acordo com o esquema de mapeamento de URLs definido no framework. Este esquema de mapeamento j vem por padro definido da seguinte maneira:

Antes de comear o ciclo de vida da aplicao, ou seja, no passo zero, o web2py ir procurar a definio deste esquema e, a partir da, procurar os respectivos itens da URL, respectivamente: aplicao, controlador, ao. A partir desta definio, o web2py ir passar os argumentos e parmetros para o controlador, que decidir qual viso ir invocar para exibir o retorno da requisio (response). Vamos pegar, por exemplo, a seguinte URL: http://127.0.0.1:8080/a/c/f.html. O web2py ir procurar um arquivo de configurao de mapeamento de URLs(routes.py), e se este arquivo for encontrado, ser aplicado o modelo definido nele. Caso este arquivo no exista, ento o web2py ir utilizar o mapeamento padro que segue o seguinte modelo:
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

60

{{ Desenvolvimento web com Python e web2py }}

Lendo do final para o incio: A funo f() definida no controlador c.py que faz parte da aplicao a, e que retorna contedo no formato HTML.

Caso a funo f no exista, o web2py redirecionar para a funo index. Caso c.py no exista, o web2py redirecionar para o controlador default e caso a no exista, o web2py redirecionar para a aplicao init e welcome respectivamente. Se nenhuma dessas condies forem satisfeitas, ento a mensagem invalid request ser exibida.

Por padro, a cada nova requisio tambm sero criadas variveis de sesso. Adicionalmente, um cookie referente a esta sesso ser enviado ao browser do cliente para manter referncia a esta sesso. A extenso html opcional e, mesmo que voc no informe, o web2py ir assumir que voc quer o retorno no formato html. A extenso em uma requisio determina a extenso da view correspondente que ir renderizar o retorno da funof(). E este mesmo contedo poderia ser servido em mltiplos formatos (html, xml, json, rss etc.).
Funes que recebem argumentos ou que iniciam com duplo underline __ no so expostas publicamente e podem ser acessadas apenas atravs de outras funes. Esta pode ser uma boa prtica de acoplamento (boxing).

Existe uma exceo a este esquema de URLs: http://127.0.../a/static/nomedeumarquivo No existe um controlador com o nome static, porm o web2py ir mapear esta requisio diretamente para a pasta de arquivos estticos de sua aplicao. E como estes arquivos no exigem processamento, quando um contedo esttico diretamente requisitado, o web2py no criar variveis de sesso, no enviar cookies ao navegador e no executar os arquivos de modelo. O web2py serve arquivos estticos em blocos de 1MB, e envia o contedo parcialmente ao navegador quando este limite ultrapassado. O web2py tambm implementa o protocolo IF_MODIFIED_SINCE (se alterado desde...) e no serve um arquivo esttico, caso ele j esteja no cache do navegador e no tenha sido alterado desde a ltima verso.

Passagem de parmetros
O web2py mapeia os parmetros POST e GET da seguinte maneira: http://127.0.0.1:8000/a/c/f.html/x/y/z?p=1&q=2 Para a funo f do controlador c.py na aplicao a, os parmetros de URL so armazenados no objeto request seguindo a seguinte estrutura:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

61

{{ Desenvolvimento web com Python e web2py }}


1. 2. 3. 4. 5. 6. 7. request.args = ['x', 'y', 'z'] request.vars = {'p':1, 'q':2} request.application = 'a' request.controller = 'c' request.function = 'f'

Nos exemplos acima, tanto request.args[i] como request.args(i) podem ser utilizados para acessar o elemento do objeto request.args, porm, enquanto o primeiro estoura uma exceo caso a lista no possua o ndice especificado, o ltimo retorna None neste caso.

1. request.url

request.url armazena a URL completa para a respectiva requisio, no incluindo os valores de POST e GET. Se a requisio HTTP GET, ento request.env.request_method ter o valor "GET"; se for POST, request.env.request_method ter o valor "POST". Variveis querystring so armazenadas no dicionrio request.vars e tambm so referenciadas em request.get_vars (GET) ou request.post_vars (POST). O web2py tambm armazena variveis de ambiente WSGI, como:
1. request.env.path_info 2. 'a/c/f' E tambm os cabealhos HTTP: 1. request.env.http_host 2. '127.0.0.1:8000' 3.

O web2py valida toda URL para prevenir ataques. As URLs podem conter apenas caracteres alfanumricos, underlines, barras, traos; os argumentos no podem conter pontos consecutivos. Todo espao em branco substitudo por um underline.

Se a URL corresponder a um arquivo esttico, o web2py retornar este arquivo, caso contrrio processar na seguinte ordem:

Checagem de cookies Criao do ambiente em que ser executada a funo requisitada Inicializao dos objetos request, response, cache Abre uma sesso existente ou inicia uma nova sesso Executa em ordem alfabtica todos os arquivos de modelo da aplicao Executa a funo requisitada
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

62

{{ Desenvolvimento web com Python e web2py }}

Se a funo requisitada retornar um dicionrio, executa a respectiva viso Em caso de sucesso, efetua a confirmao (commit) de todas as transaes abertas Salva a sesso Retorna um objeto HTTP response

Vises e controladores so executados em diferentes cpias do mesmo ambiente, desta forma, as vises no visualizam os controladores, mas podem ver os modelos e tambm podem ver as variveis retornadas pelo controlador.

Se algum erro ou exceo que no seja HTTP acontecer:


Armazena o retorno do erro e referencia um ticket para este erro Reverte (rollback) todas as transaes abertas Retorna uma tela com o nmero e link para o ticket de erro

API
Modelos, Vises e Controladores so executados em um ambiente onde so importados e ficam disponveis os seguintes objetos:

Objetos globais:
request, response, session, cache

Navegao:
redirect, HTTP

internacionalizao (i18n):
T

Helpers (bibliotecas auxiliares):


XML, URL, BEAUTIFY A, B, BEAUTIFY, BODY, BR, CENTER, CODE, DIV, EM, EMBED, FIELDSET, FORM, H1, H2, H3, H4, H5, H6, HEAD, HR, HTML, I, IFRAME, IMG, INPUT, LABEL, LEGEND, LI, LINK, OL, UL, MARKMIN, MENU, META, OBJECT, ON, OPTION, P, PRE, SCRIPT, OPTGROUP, SELECT, SPAN, STYLE, TABLE, TAG, TD, TEXTAREA, TH, THEAD, TBODY, TFOOT, TITLE, TR, TT, URL, XHTML, xmlescape, embed64

Validadores:
CLEANUP, CRYPT, IS_ALPHANUMERIC, IS_DATE_IN_RANGE, IS_DATE, IS_DATETIME_IN_RANGE, IS_DATETIME, IS_DECIMAL_IN_RANGE, IS_EMAIL, IS_EMPTY_OR, IS_EXPR, IS_FLOAT_IN_RANGE, IS_IMAGE, IS_IN_DB, IS_IN_SET, IS_INT_IN_RANGE, IS_IPV4, IS_LENGTH, IS_LIST_OF, IS_LOWER, IS_MATCH, IS_EQUAL_TO,
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

63

{{ Desenvolvimento web com Python e web2py }}

IS_NOT_EMPTY, IS_NOT_IN_DB, IS_NULL_OR, IS_SLUG, IS_STRONG, IS_TIME, IS_UPLOAD_FILENAME, IS_UPPER, IS_URL

Banco de dados:
DAL, Field Outros objetos e mdulos so definidos nas bibliotecas, mas eles no so automaticamente importados at que sejam utilizados. As principais entidades da API no ambiente de execuo web2py so: request, response, session, cache, URL, HTTP, redirect e T. Alguns objetos e funes, incluindo Auth (autenticao), Crud (formulrios) e Service (webservices), so definidos no mdulo gluon/tools.py e necessitam serem importados caso sejam necessrios.
1. from gluon.tools import Auth, Crud, Service

Renderizao de contedo
Como j foi discutido anteriormente, o web2py mapeia as funes Python (as aes) definidas nos controladores como sendo a porta de entrada para a requisio. Caso esta funo retorne um dicionrio de dados, o web2py ento renderiza a viso correspondente com a funo+extenso. Caso o controlador retorne um objeto string, por exemplo, isto tambm ser renderizado em uma view, pois strings podem ser serializadas como dicionrio, e este exemplo serve para qualquer outro objeto com esta caracterstica: um dicionrio ou pode ser serializado como um. Podemos criar vises especficas para cada ao, podemos utilizar uma nica viso para renderizar contedo de vrias aes e tambm podemos ter varias vises que renderizam contedo de uma nica ao. Caso o web2py no encontre uma viso especifica para renderizar o contedo de uma ao, ento ele renderizar utizando as vises genricas; por padro temos uma view genrica para cada um dos seguintes tipos de contedo:

/views/generic.html renderiza contedo de aes requisitadas que no possuam extenso ou que tenham a extenso .html /views/generic.json requisies com a extenso .json /views/generic.xml requisies com a extenso .xml /views/generic.load requisies com a extenso .load (usado para componentes e Ajax)

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

64

{{ Desenvolvimento web com Python e web2py }}

Tambm possvel renderizar o contedo em formato rss em /views/generic.rss, mas este um caso especial, onde o dicionrio retornado pela ao deve respeitar um formato rss vlido. Outra possibilidade a criao de sua prpria viso genrica. Implementando seu prprio serializador, ou utilizando uma biblioteca especfica, possvel ter uma viso genrica /views/generic.xls para renderizar o contedo do dicionrio com o formato .xls(Microsoft Excel), ou qualquer outro tipo de retorno. Exemplos: Em uma aplicao de teste, dentro do controlador default.py, defina a seguinte ao:
1. def aluno(): 2. agora = request.now 3. return dict(nome='Fulano', curso='web2py', idade=27, dia=agora.date(), hora=agora.time())

Agora faa um request em outra aba ou janela do seu navegador para o endereo da funo (ao) aluno

http://127.0.0.1:8080/<suaapp>/default/aluno Mesmo no informando a extenso, o web2py assume o padro e renderiza o contedo em formato HTML. Experimente agora:

http://127.0.0.1:8080/<suaapp>/default/aluno.html http://127.0.0.1:8080/<suaapp>/default/aluno.xml http://127.0.0.1:8080/<suaapp>/default/aluno.load http://127.0.0.1:8080/<suaapp>/default/aluno.json Como RSS contm um formato fixo, o retorno de um controlador em formato RSS precisa obedecer seguinte estrutura:
1. def feed(): 2. return dict(title="meu rss", 3. link="http://feed.minhaapp.com", 4. description="meu primeiro feed com web2py", 5. entries=[ 6. dict(title="web2py framework", 7. link="http://feed.minhaapp.com/web2py", 8. description="meu primeiro item - Python Show!") 9. ])

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

65

{{ Desenvolvimento web com Python e web2py }}

Agora acesse:

http://127.0.0.1:8080/<suaapp>/default/feed.html http://127.0.0.1:8080/<suaapp>/default/feed.xml http://127.0.0.1:8080/<suaapp>/default/feed.json http://127.0.0.1:8080/<suaapp>/default/feed.load http://127.0.0.1:8080/<suaapp>/default/feed.rss Alm das formas explanadas aqui, tambm possvel renderizar contedo atravs de servios (web-services), que podem ser SOA, SOAP, XML-RPC, REST, etc., porm, este assunto ser abordado no mdulo avanado deste treinamento. response Outra maneira de enviar contedo para a viso utilizando a funo write do objeto response, que tem por objetivo escrever direta e intrusivamente no corpo do html retornado. Altere a ao aluno
1. def aluno(): 2. response.write('escrito diretamente pelo response') 3. agora = request.now 4. return dict(nome='SeuNome', curso='web2py', idade=27, dia=agora.date(), hora=agora.time())

acesse: http://127.0.0.1:8080/<suaapp>/default/aluno.load e repare que o response.write escreveu contedo no corpo da viso, e que este contedo escrito antes de ser efetuado o retorno do dicionrio. Mtodos e propriedades do objeto response response.write pode receber qualquer objeto string ou que possa ser serializado como string. O objeto response um container transportador de respostas; o web2py implementa em seu layout padro o objeto response como container para algumas informaes importantes que so renderizadas no <HEAD> do HTML: response.cookies: responsvel pelo envio de cookies. response.download(request, db): mtodo implementado para a criao da funcionalidade de download de arquivos. response.files: uma lista de arquivos CSS e JS que sero includos no header do layout padro. Para incluir um arquivo CSS ou JS apenas inclua um novo objeto a esta lista. Ele resolver o problema de duplicidade. A ordem importante. response.flash: objeto opcional para armazenar uma mensagem de status a ser exibida nas vises. response.headers: dicionrio para cabealhos HTTP.
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

66

{{ Desenvolvimento web com Python e web2py }}

response.menu: parmetro opcional para ser usado pelo Helper MENU para a criao de menus. response.meta: um dicionrio contendo as informaes de META, geralmente utilizado em otimizao para busca (SEO), como por exemplo response.meta.author, response.meta.description, e/ou response.meta.keywords. O contedo de META automaticamente includo no local da tag META do html, e o arquivo "web2py_ajax.html" que responsvel por esta incluso. response.render(view, vars): um mtodo utilizado para invocar diretamente uma viso atravs de um controlador. response.stream(file, chunk_size): quando um controlador retorna este tipo de objeto, o web2py efetua o stream deste arquivo em blocos de 1MB. response.title: opcional. Deve conter o ttulo da pgina a ser renderizado pela tag HTML <title> no header de uma viso. response._vars: acessvel apenas pela viso, e contm o retorno do controlador para a viso. response.view: o nome da viso a ser renderizada por padro naquele controlador. response.write(text): escreve textos no corpo <body> da viso renderizada. No existem restries quanto ao uso de response para a passagem de parmetros. Voc pode criar novos itens no dicionrio response, mas recomendado manter apenas os seguintes:
1. 2. 3. 4. 5. 6. 7. 8. response.title response.subtitle response.flash response.menu response.meta.author response.meta.description response.meta.keywords response.meta.*

Session
Session um dicionrio que armazena valores que ficam disponveis em todo o escopo da aplicao; como a sesso iniciada antes da execuo dos modelos, o acesso a este objeto global.
A sintaxe simples: 1. 2. 3. 4. 5. 6. 7.

#definio session.minhavariavel = 'valor' #acesso a = session.minhavariavel ou a = session['minhavariavel']

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

67

{{ Desenvolvimento web com Python e web2py }}

Redirecionamento
O redirecionamento de url feito atravs da funo redirect, que pode ser chamada em qualquer modelo, controlador ou viso.
1. redirect('http://www.web2pybrasil.com.br')

O cdigo acima faz com que o web2py invoque uma exceo HTTP que efetua o output deste redirecionamento para o navegador, quebrando o fluxo normal do cdigo no momento em que chamada.

URL
Uma das funes mais importantes no web2py a funo URL. Ela gera uma URL que pode ser mapeada dinamicamente para aes dos controladores e arquivos estticos. Por exemplo:
1. URL('aluno')

Ser mapeada para:


1. /<applicao>/<controlador>/aluno

Note que a sada da funo URL neste caso depende dinamicamente do nome da aplicao que est sendo executada, do controller que foi invocado e dos parmetros que tenham sido recebidos. Por exemplo:
1. URL('aluno', args=['x','y'], vars=dict(z='t'))

Ser mapeado em:


1. /<applicao>/<controlador>/aluno/x/y?z=t

possvel especificar explicitamente os parmetros da funo URL, e esta uma prtica recomendada:
1. a = aplicao 2. c = controlador 3. f = funo

Desta forma:
1. URL(a='minhaapp', c='default', f='aluno')

Ser:
1. /minhaapp/default/aluno

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

68

{{ Desenvolvimento web com Python e web2py }}

Para os arquivos estticos armazenados na pasta static, o web2py prov um controlador virtual que deve ser usado para gerar URLs para estes arquivos.
1. URL('static', 'imagem.png')

Ser mapeado diretamente para a URL do arquivo: /<aplicao/static/imagem.png

Autenticao e Controle de Acesso


O web2py inclui um poderoso e customizvel sistema de controle de acesso baseado em papis (RBAC). Este sistema implementado na classe Auth que necessita e implementa as seguintes tabelas: auth_user armazena o nome do usurio, o endereo de e-mail, a senha e a situao do registro do usurio ( pendente, aceito ou bloqueado) auth_group armazena os grupos ou os papis para os usurios. Por padro cada novo usurio criado possui seu prprio grupo, porm, cada usurio pode fazer parte de mltiplos grupos, e cada grupo pode conter diversos usurios. auth_membership efetua o relacionamento entre usurios e grupos em uma estrutura muitos-para-muitos. auth_permission efetua o relacionamento entre grupos e permisses. Uma permisso identifica por um nome e opcionalmente por uma tabela e um registro. Por exemplo, membros de um certo grupo podem executar update em um registro especfico de uma tabela. auth_event armazena o log do sistema de autenticao. Uma vez criados os usurios, grupos, participaes, permisses e relacionamentos, o web2py ir prover uma API para verificar se um usurio est logado, se pertence a um grupo e se este grupo possui uma determinada permisso. O web2py tambm prov decoradores de funo que podem ser utilizados para restringir acesso a qualquer ao baseando-se no usurio, grupo e permisses. O web2py tambm gerencia tipos especficos de permisses, as permisses que correspondem aos mtodos CRUD (create, read, update, delete) e faz isso automaticamente, sem a necessidade do uso de decoradores.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

69

{{ Desenvolvimento web com Python e web2py }}

Autenticao
Para utilizar o sistema RBAC, os usurios precisam estar identificados. Isso significa que eles precisam se registrar (ou serem registrados) para fazer o login. Auth prov mltiplas formas de login. A padro consiste em uma identificao baseada na tabela auth_user. Como alternativa, voc pode autenticar seus usurios utilizando servios de terceiros ou provedores de autenticao como, por exemplo, Google, PAM, LDAP, FaceBook, LinkedIn, OpenID, Oauth etc. Para comear a utilizar Auth, voc precisa definir no nvel do model o seguinte cdigo:
Note que este trecho de cdigo j est definido na aplicao welcome, que serve de template para novas aplicaes no web2py. 1. form gluon.tools import Auth 2. auth = Auth(globals(), db) 3. auth.define_tables(username=False)

Se voc desejar utilizar o username ao invs do e-mail (padro), atribua True no parmetro username. Para expor a ao de autenticao, por exemplo, no controlador default.py:
1. def user(): 2. return dict(form=auth())

O web2py tambm possui uma view (default/user.html) padro para renderizar a funo de login:
1. 2. 3. 4. 5. 6. 7. {{extend 'layout.html'}} <h2>{{=request.args(0)}}</h2> {{=form}} {{if request.args(0)=='login':}} <a href="{{=URL(args='register')}}" >register</a><br /> <a href="{{=URL(args='request_reset_password')}}" >lost password</a><br /> {{pass}}

Esta funo simplesmente exibe um formulrio de login e voc pode customiz-la utilizando qualquer outro recurso do framework. A nica condio que o formulrio a ser exibido depende do valor de request.args(0), portanto, voc sempre ter que manter um bloco if como este:
1. {{if request.args(0)=='login':}}Formulrio customizado...{{pass}}


[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

70

{{ Desenvolvimento web com Python e web2py }}

O controlador e a view acima expem multiplas aes: http://.../[app]/default/user/register http://.../[app]/default/user/login http://.../[app]/default/user/logout http://.../[app]/default/user/profile http://.../[app]/default/user/change_password http://.../[app]/default/user/verify_email http://.../[app]/default/user/retrieve_username http://.../[app]/default/user/request_reset_password http://.../[app]/default/user/reset_password http://.../[app]/default/user/impersonate http://.../[app]/default/user/groups http://.../[app]/default/user/not_authorized register permite que usurios se registrem, est integrado com um CAPTCHA que vem desabilitado por padro. login permite que um usurio registrado efetue login. logout permite que o usurio efetue logout. profile permite que os usurios alterem informaes de seu perfil (o contedo da tabela auth_user, que no possui estrutura fixa, e pode ser customizada). change_password permite alterao de senhas. verify_email caso a verificao via e-mail esteja habilidada, espera-se que o usurio receba um e-mail de confirmao de seu registro; este e-mail contm um link apontando para esta ao. retrieve_username permite que um usurio receba via e-mail seu nome de usurio informando seu e-mail. request_reset_password permite que um usurio requisite a redefinio de sua senha caso tenha esquecido. impersonate permite que um usurio se passe por outro usurio, isto til para depurao e testes, e s permitido caso o usurio possua a permisso impersonate. groups lista os grupos nos quais o usurio logado est contido. not_authorized exibe uma mensagem de erro caso o usurio tente acessar algo para o qual ele no tenha permisso de acesso. navbar um helper que constri dinamicamente os links para login, logout, etc. As aes logout, profile, change_password, impersonate e groups requerem login para serem acessadas. Por padro tudo exposto, porm, possvel restringir o acesso a apenas algumas dessas aes. Todos os mtodos mencionados acima podem ser estendidos ou substitudos atravs da herana da classe Auth.
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

71

{{ Desenvolvimento web com Python e web2py }}

Restringindo acesso

Para restringir acesso a uma funo, permitindo apenas que usurios logados a acessem, utilizamos o decorador @auth.requires_login()
1. @auth.requires_login(): 2. def segredo(): 3. return dict(message='Bem vindo %(first_name)s' % auth.user) 4.


auth.user um dicionrio contendo uma cpia dos registros de db.auth_user para o usurio que est atualmente logado. H tambm o auth.user_id, que armazena o mesmo auth.user.id que armazena apenas o id do usurio.

Restrioes no registro de usurios


Se voc deseja que os visitantes registrem-se, mas s acessem o sistema aps receberem aprovao do administrador, defina no model:
1. auth.settings.registration_requires_approval = True

Caso voc queira restringir o acesso pgina de registro:


1. auth.settings.actions_disabled.append('register')

Integrao com autenticao externa: Facebook, Google, Twitter etc.


Voc pode continuar utilizando a camada de controle de acesso do web2py, porm utilizando servios externos para efetuar a autenticao. O web2py fornece um mdulo que implementa a autenticao com servios como Google, Twitter, Facebook, LinkedIn, Myspace, Flickr etc. A maneira mais fcil, e que j vem com implementao de exemplo da aplicao welcome, utilizando o servio (Janrain.com). Janrain.com um servio que prov a ponte entre a sua autenticao e os provedores de assinatura. Voc pode registrar-se para uma conta gratuita do janrain.com e utilizar da seguinte maneira:
1. from gluon.contrib.login_methods.rpx_account import RPXAccount 2. auth.settings.actions_disabled=['register','change_password','request_reset_password'] 3. auth.settings.login_form = RPXAccount(request, 4. api_key='...', 5. domain='...', 6. url = "http://localhost:8000/%s/default/user/login" % request.application)

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

72

{{ Desenvolvimento web com Python e web2py }}

Quando um novo usurio fizer login no web2py atravs de um destes servios, sero criados os registros necessrios para que este usurio seja uma entidade do Auth e seu e-mail ficar armazenado na tabela db.auth_user. O web2py armazenar um registration_id baseado na identidade utilizada, para garantir que este usurio um registro nico. Voc pode customizar o mapeamendo de dados fornecidos pelo jainrain.com com os dados de sua tabela de usuriosauth_user. Exemplo para o Facebook:
1. auth.settings.login_form.mappings.Facebook = lambda profile:\ 2. dict(registration_id = profile["identifier"], 3. username = profile["preferredUsername"], 4. email = profile["email"], 5. first_name = profile["name"]["givenName"], 6. last_name = profile["name"]["familyName"])

Se voc preferir utilizar diretamente os meios de autenticao (Google, Facebook, OpenID, Oauth), voc pode eliminar a necessidade do cadastro com o jainrain.com e implementar seu prprio sistema de autenticao customizado.

Autorizao
Usurios pertencem a grupos. Cada grupo possui uma identificao. Grupos possuem permisses. Usurios possuem permisses herdadas dos grupos aos quais pertencem. Voc pode criar grupos, incluir usurios e permisses via appadmin: Considerando que possumos um grupo chamado RH (Funcionrios do depto de RH), podemos checar se o usurio logado atualmente possui associao a este grupo e desta maneira controlar o acesso a aes. Decoradores
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

73

{{ Desenvolvimento web com Python e web2py }}

A maneira mais comum para checar as permisses de acesso com o uso de decoradores de funo:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. def acao_publica(): return 'essa funo pblica' @auth.requires_login() def acao_protegida(): return 'esta funo requer que o usurio esteja logado' @auth.requires_membership('RH') def acao_protegida_porgrupo(): return 'esta funo requer que o usurio logado seja membro do grupo RH' @auth.requires(auth.user_id==1 or request.client=='127.0.0.1') def acao_protegida_por_condicao(): return 'esta funo requer que o usurio tenha o id 1 e o IP 127.0.0.1'

Note que todas as funes, exceto a primeira, possuem restries baseadas no login do usurio. Caso o usurio no esteja logado e as permisses no possam ser checadas, o web2py redireciona o usurio para a pgina de login. Se um usurio logado no possuir a permisso de acesso a uma determinada ao, o web2py redireciona para uma pgina que pode ser configurada em models com:
1. auth.settings.on_failed_authorization = \ 2. URL('acao_a_direcionar')

Marcao de templates com Python


Assim como nos models e controllers, o web2py utiliza a prpria linguagem Python para a marcao de template das views. Nas views possvel escrever qualquer tipo de cdigo de marcao, como HTML, XML, CSS, JavaScript e embutir cdigo Python no meio, e isso faz com que voc tenha uma maior flexibilidade para gerar o contedo da maneira que quiser, podendo, por exemplo, programar o formato de sada de uma view em .csv, .rss ou at mesmo .xls do Microsoft Excel. O web2py executa as views em uma cpia separada do ambiente de execuo da aplicao. Para isso, transforma todo o cdigo de marcao da view em um mdulo com puro cdigo Python - por este motivo, a execuo da views rpida.

O cdigo da view no precisa seguir regras de endentaco do Python A marcao para escape feita dentro de {{ e }} Blocos de cdigo comeam nas linhas {{}} terminadas em : Blocos de cdigo terminam onde encontram a instruo {{pass}} Nos casos em que a construo do bloco for clara, no ser preciso usar o {{pass}}
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

74

{{ Desenvolvimento web com Python e web2py }}


Apesar de o padro MVC recomendar que se utilize as vises apenas para exibir contedo, com o web2py temos a flexibilidade de escolher como implementaremos nosso cdigo, de qualquer forma, o web2py sempre encoraja o desenvolvedor a utilizar corretamente o padro MVC e suas boas prticas.

Tudo o que est entre {{...}} ser executado como cdigo Python. Alm disso, o web2py especifica algumas palavras-chave para ajudar no processo de criao de views. So elas:

{{=expresso_Python}}: executa expresso_Python e imprime o resultado no local. {{extend 'arquivo.html'}}: utiliza a view arquivo.html como base para essa view. {{include}}: indica onde outras views que utilizam essa como base sero adicionadas. {{pass}}: marca o trmino de um bloco de cdigo. Pode parecer estranho, acima, o uso da keyword pass. Ela usada por causa de uma definio no sistema de apresentao do web2py: por conta de espaos na camada de apresentao fazerem diferena, seria complicado em todos os casos o programador manter a endentao correta do cdigo. Para resolver esse problema o web2py ento gera um novo cdigo baseado em nossa view, ignorando a endentao que utilizamos - ele auto-endenta o cdigo quando encontra if, for etc. Para voltar um nvel, como a endentao na view ignorada, precisamos utilizar a palavra reservada do Python pass. Note que essa palavra reservada faz parte da linguagem Python e sua funo apenas "passar" (no executa comando algum) nesse caso, ela serve como um sinal para o web2py voltar um nvel na endentao.

escopo e parmetros
Como as views so executadas em um ambiente paralelo ao ambiente de execuo dos controllers, elas no tm acesso ao que definido nas funes, ao menos que sejam variveis de sesso ou o prprio retorno de uma funo. Mas as views tm acesso a todo o restante do escopo da aplicao, portanto qualquer funo, objeto ou varivel definidos nos models ficaro acessveis para todas as views. Desta mesma forma, o web2py j implementa alguns mtodos prprios que podem ser utilizados tanto nas views, quanto nos controllers.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

75

{{ Desenvolvimento web com Python e web2py }}

HTML Helpers
Considere o seguinte cdigo em uma view:
1. {{=DIV('isto', '', 'um', 'teste', _id='123', _class='minhaclasse')}}

Que ser renderizado como:


1. <div id="123" class="minhaclasse">istoumteste</div>

DIV, por exemplo, uma classe helper, um tipo de classe que pode ser usada para criar HTML programaticamente. Em uma classe helper, os argumentos so interpretados como objetos contidos dentro da tag HTML. Os argumentos nomeados que iniciam com um underline sero interpretados como atributos. Alguns helpers recebem argumentos nomeados que no iniciam com underline; estes argumentos so especficos para cada tipo de TAG. TAGS A, B, BEAUTIFY, BODY, BR, CENTER, CODE, DIV, EM, EMBED, FIELDSET, FORM, H1, H2, H3, H4, H5, H6, HEAD, HR, HTML, I, IFRAME, IMG, INPUT, LABEL, LEGEND, LI, LINK, OL, UL, MARKMIN, MENU, META, OBJECT, ON, OPTION, P, PRE, SCRIPT, OPTGROUP, SELECT, SPAN, STYLE, TABLE, TAG, TD, TEXTAREA, TH, THEAD, TBODY, TFOOT, TITLE, TR, TT, URL, XHTML, XML, xmlescape, embed64 As tags podem ser agrupadas para gerar cdigos HTML mais complexos:
1. {{=DIV(B(I("hello ", "<world>"))), _class="myclass")}}

renderizado como:
1. <div class="myclass"><b><i>hello <world></i></b></div>

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

76

{{ Desenvolvimento web com Python e web2py }}

Document Object Model (DOM). Os helpers do web2py so muito mais do que um simples mecanismo para gerao de HTML sem a necessidade de concatenao de strings. Eles provem uma implementao do DOM no servidor. Objetos podem ser referenciados pela sua posio; exemplo:
1. 2. 3. 4. 5. 6. 7. 8. >>> a = DIV(SPAN('a', 'b'), 'c') >>> print a <div><span>ab</span>c</div> >>> del a[1] >>> a.append(B('x')) >>> a[0][0] = 'y' >>> print a <div><span>yb</span><b>x</b></div>

Atributos de um helper podem ser acessados atravs de seu nome, e o comportamento semelhante ao de uma lista:
1. 2. 3. 4. 5. >>> >>> >>> >>> <div a = DIV(SPAN('a', 'b'), 'c') a['_class'] = 's' a[0]['_class'] = 't' print a class="s"><span class="t">ab</span>c</div>

XML, por exemplo, um objeto usado para encapsular texto que no deve ser escapado, ou seja, ser passado diretamente para o navegador. Este texto pode ou no conter XML vlido, podendo ser cdigo CSS ou Java Script.
1. >>> print DIV("<b>ol</b>") 2. &lt;b&gt;ol&lt;/b&gt;

Usando XML possvel prevenir o escape:


1. >>> print DIV(XML("<b>ol</b>")) 2. <b>ol</b>

SCRIPT inclui ou cria um link para um script JavaScript:


1. 2. 3. 4. >>> print SCRIPT('alert("hello world");', _language='javascript') <script language="javascript"><!-alert("hello world"); //--></script>

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

77

{{ Desenvolvimento web com Python e web2py }}

Formulrios
O HTML helper FORM o responsvel pela criao de formulrios no web2py. Voc pode utilizar FORM para criar formulrios diretamente na view, ou cri-los no controller e ento enviar o formulrio como resposta para a view. O helper FORM apenas cria uma TAG HTML <form>.</form>, e como todos os outros helpers, possui inteligncia para conhecer os elementos inseridos dentro dele.

Criao de formulrio no controller utilizando FORM O mtodo append insere novos elementos em FORM.
1. def index(): 2. form = FORM(_action='', _method='post') 3. form.append(LABEL('nome')) 4. form.append(INPUT(_name='nome', type='text')) 5. form.append(BR()) 6. form.append(LABEL('curso')) 7. form.append(INPUT(_name='curso',_type='text')) 8. form.append(BR()) 9. form.append(INPUT(_value='enviar',_type='submit')) 10. return dict(form=form)

Criamos o formulrio utilizando o helper FORM e armazenamos no objeto form, ento retornamos um dicionrio contendo form que ser visvel pela view. O seguinte cdigo na respectiva view j ser suficiente para testar este formulrio:
1. 2. 3. 4. {{extend 'layout.html'}} <br> {{=form}} {{=BEAUTIFY(request.vars)}}

{{=form}} renderiza o formulrio, enquanto {{=BEAUTIFY(request.vars)}} formata e exibe o resultado do post deste formulrio.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

78

{{ Desenvolvimento web com Python e web2py }}

Criao de formulrio diretamente na view Em uma view voc obviamente poderia criar o formulrio utilizando as prprias tags HTML <form>, porm, s vezes muito til utilizar os HELPERS mesmo diretamente na view. Considere o controller
1. def index(): 2. return dict()

E ento na view default/index.html


1. {{extend 'layout.html'}} 2. 3. {{=FORM(LABEL('nome'), INPUT(_name='nome', type='text'), BR(), LABEL('curso'), 4. INPUT(_name='curso',_type='text'), BR(), INPUT(_value='enviar',_type='submit'), 5. _action='', _method='post')}} 6. 7. {{=BEAUTIFY(request.vars)}}

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

79

{{ Desenvolvimento web com Python e web2py }}

Validao de formulrios
Os validadores de formulrio so os mesmos discutidos no capitulo Tipos de dados e Validaes, porm, no caso dos formulrios, no consideramos os validadores do nvel do banco de dados. Alterando nosso primeiro exemplo, podemos incluir a validao em seus campos:

No controller altere a funo index()


1. def index(): 2. # criao de uma DIV para servir de container 3. container = DIV(_class='container') 4. 5. # criao do formulrio 6. form = FORM(_action='', _method='post') 7. form.append(LABEL('nome')) 8. form.append(INPUT(_name='nome', 9. requires=IS_NOT_EMPTY(error_message='Preencha seu nome'), 10. type='text')) 11. form.append(BR()) 12. form.append(LABEL('curso')) 13. form.append(INPUT(_name='curso',_type='text')) 14. form.append(BR()) 15. form.append(INPUT(_value='enviar',_type='submit')) 16. 17. # incluso do formulrio dentro da DIV container 18. container.append(form) 19. 20. # validao do formulrio 21. 22. if form.accepts(request.vars, session): 23. response.flash = 'Sucesso' 24. container = DIV(H3('Dados enviados com sucesso! Obrigado'),_class='container') 25. elif form.errors: 26. response.flash = 'Erros encontrados, tente novamente' 27. return dict(container=container)

Inserimos um objeto container, contendo uma <div> criada com o HTML helper DIV No campo *nome** do formulrio inclumos o validador IS_NOT_EMPTY Inserimos o objeto form dentro do objeto container > <div><form>..</form></div> Inclumos um bloco condicional que valida o retorno do mtodo accepts Caso o formulrio seja aceito pela validao, reiniciamos o objeto container e inclumos uma mensagem no lugar do formulrio Efetuamos o retorno do objeto container para ser inserido na view
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

80

{{ Desenvolvimento web com Python e web2py }}

A view default/index.html:
1. 2. 3. 4. 5. 6. {{extend 'layout.html'}} <br> {{=container}} {{=BEAUTIFY(request.vars)}}

Se o formulrio no passar pela validao (por exemplo, se o campo nome estiver vazio), o validador IS_NOT_EMPTY exibir uma mensagem:

Em caso de sucesso:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

81

{{ Desenvolvimento web com Python e web2py }}


O web2py valida os formulrios atravs do mtodo accepts e garante que os dados no sejam inseridos em duplicidade, para isso cria uma varivel de sesso contendo um id nico identificando o formulrio.

Criao de formulrios automaticamente atravs do banco de dados


Esta a forma mais interessante para a criao de formulrios no web2py. Atravs de uma tabela do banco de dados, podemos criar formulrios automaticamente: Considerando o seguinte arquivo de model:
1. 2. 3. 4. 5. 6. 7. 8. 9. db = DAL('sqlite://storage.sqlite') db.define_table('carro', Field('marca'), Field('modelo'), Field('foto','upload')) db.carro.marca.requires=IS_IN_SET(('Toyota','GM','Volvo', 'Renault'), error_message='Insira um valor vlido') db.carro.modelo.requires=IS_NOT_EMPTY(error_message='No pode ser em branco')

No model definimos uma tabela carro, possuindo os campos marca e modelo, cada um com seus validadores. Repare que inserimos um campo chamado foto do tipo upload - este um tipo especial para o web2py, e este campo servir para armazenar o caminho de um arquivo que receberemos atravs de um campo de upload no formulrio (os arquivos sero armazenados na pasta /<aplicao>/uploads/carro.image.XXXX.jpg). Utilizando o helper SQLFORM, podemos criar um formulrio de insero de dados para esta tabela. No arquivo de controller inclua:
1. def carro(): 2. # criamos um formulrio a partir da tabela de carros 3. form = SQLFORM(db.carro) 4. 5. if form.accepts(request.vars, session): 6. response.flash = 'Sucesso' 7. elif form.errors: 8. response.flash = 'Erros' 9. else: 10. response.flash = 'Preencha os dados' 11. 12. return dict(form=form) 13.

Agora visite a seguinte URL: http://127.0.0.1:8000/<aplicao>/default/carro

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

82

{{ Desenvolvimento web com Python e web2py }}

O helper SQLFORM cria um formulrio baseando-se nos campos e nos validadores de uma tabela. A validao final deste formulrio pode ser feita na prpria ao que est gerando o formulrio utilizando o mtodo accepts.

Download
Com o arquivo armazenado na pasta upload da aplicao, podemos exibi-lo utilizando a funo download que j est definida no controller default.py
1. def download(): 2. return response.download(request, db)

Como o caminho e o nome (que gerado randomicamente para o arquivo que foi enviado) so armazenados na varivel request.vars.image, podemos us-la para gerar a visualizao desta imagem. Vamos criar uma nova ao que servir para editar os dados de um carro existente na tabela carro:
1. def mostracarro(): 2. record = db.carro(request.args(0)) or redirect(URL('index')) 3. form = SQLFORM(db.carro, record, deletable=True, 4. upload=URL('download')) 5. if form.accepts(request.vars, session): 6. response.flash = 'Sucesso' 7. elif form.errors: 8. response.flash = 'Erros' 9. return dict(form=form)

Repare que recebemos o id de um carro atravs do objeto request e na hora de criar o formulrio com SQLFORM, passamos o nome da tabela db.carro e o registro referente ao id recebido. O argumento deletable determina se ser possvel excluir um registro atravs deste formulrio e o argumento upload indica qual URL dever ser usada para exibio da imagem; neste caso indicamos a funo download. Supondo que o id do carro que voc inseriu seja 1, a pgina http://.../< aplicao >/default/mostracarro/1 exibir o seguinte formulrio.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

83

{{ Desenvolvimento web com Python e web2py }}

CRUD
Para facilitar ainda mais o trabalho com formulrios, o web2py implementa uma API para o tratamento dos registros no banco de dados. Esta API oferece os mtodos CRUD (create, read, update, delete). importante observar que CRUD diferente de outros mdulos do framework, pois precisamos importar explicitamente caso queiramos utilizar.
1. 2. 3. 4. 5. 6.

# No arquivo de model
from gluon.tools import Crud crud = Crud(globals(), db) # passamos o banco de dados db como parmetro

Funes CRUD crud.tables() retorna a lista de tabelas do banco de dados. crud.create(db.tablename) retorna um formulrio para criao de novos registros. crud.read(db.tablename, id) retorna um formulrio somente leitura. crud.update(db.tablename, id) retorna um formulrio de atualizao do registro (id). crud.delete(db.tablename, id) exclui o registro (id). crud.select(db.tablename, query) retorna uma listagem de registros da tabela. crud.search(db.tablename) retorna um formulrio de busca. crud() retorna uma das funes acima baseando-se em request.args().
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

84

{{ Desenvolvimento web com Python e web2py }}

Agora podemos criar no controller uma ao para executar as operaes do CRUD:


1. def dados(): 2. return dict(form=crud()) 3.

Com esta simples ao o web2py, atravs do form=crud(), ir expor as seguintes URLs:


http://.../[app]/[controller]/[ao]/tables app/default/dados/tables

http://.../[app]/[controller]/[ao]/select/[nomedatabela] app/default/dados/select/carro

http://.../[app]/[controller]/[ao]/read/[nomedatabela]/[id] app/default/dados/read/carro/1

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

85

{{ Desenvolvimento web com Python e web2py }}

E seguindo o mesmo modelo expe todas as aes CRUD http://.../[app]/[controller]/[ao]/update/[nomedatabela]/[id] http://.../[app]/[controller]/[ao]/delete/[nomedatabela]/[id] http://.../[app]/[controller]/[ao]/search/[nomedatabela] Para implementar validao e controle de permisses das funes CRUD, basta definir a varivel crud.settings.auth = None e criar as permisses baseadas em registros.

JQuery
A aplicao de modelo do web2py welcome j vem com a biblioteca JQuery, incluindo os plugins JQuery calendar, SuperFish Menus e muitas funes customizadas baseadas em JQuery. Voc pode utilizar qualquer outra biblioteca javaScript, como: Prototype, ExtJS, Mochkit etc. No layout da aplicao modelo includo um arquivo com vrias funes JS:
1. view/web2py_ajax.html

Quando o web2py cria os formulrios e seus validadores, utiliza as funes JQuery deste arquivo e os arquivos CSS definidos em layout.html para decorar os formulrios. Exemplo de JQuery Calendar em um campo do tipo datetime em um formulrio criado com SQLFORM ou CRUD:

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

86

{{ Desenvolvimento web com Python e web2py }}

Funes JQuery podem ser includas nos Helpers. Exemplo:


1. {{=DIV('clique aqui !', _onclick="jQuery(this).fadeOut()")}}

O cdigo acima cria uma div que ao ser clicada desaparece lentamente.

Ajax
A funo ajax definida no arquivo web2py_ajax.html uma funo que efetua uma chamada a uma URL assincronamente. Esta funo sempre retorna uma resposta que poder ser embutida na sua pgina sem a necessidade de atualizao. A funo ajax segue a seguinte sintaxe:
1. ajax(url, [id1, id2, ...], target)

Exemplo de implementao:
1. def repetemeunome(): 2. form = FORM(INPUT(_id='nome', _name='nome', _onkeyup="ajax('executacomajax', 3. ['nome'], 'target')")) 4. target = DIV(_id='target') 5. return dict(form=form, target=target) 6. 7. def executacomajax(): return str(request.vars.nome +' ') * 10

A funo repetemeunome criar um formulrio com um campo nome. Neste campo, a cada caractere digitado, a funo executacomajax ser invocada e o retorno desta funo ser includo na div target. Tudo isso acontece dinamicamente sem a necessidade de atualizao da pgina.

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

87

{{ Desenvolvimento web com Python e web2py }}

web2py na web
Onde encontrar ajuda:
1. Grupo de usurios no google: a. http://groups.google.com/group/web2py-users-brazil b. http://groups.google.com/group/web2py 2. Site comunitrio brasileiro: a. http://www.web2pybrasil.com.br b. http://web2pybrasil.appspot.com c. http://twitter.com/web2pybrasil

Onde contribuir:
1. Rede de desenvolvedores voluntrios: a. http://openhatch.org/+projects/web2py b. http://web2py.uservoice.com/forums/42577-general c. http://www.web2pybrasil.com.br

Recursos:
Aplicaes e exemplos: o http://www.web2pyslices.com o http://web2py.com/appliances

[ http://www.web2pybrasil.com.br ,

http://www.temporealeventos.com.br ]

88

{{ Desenvolvimento web com Python e web2py }}

Instrutores:
Bruno Cezar Rocha

@rochacbruno
Desenvolvedor e consultor web. Possui mais de 9 anos de experincia em desenvolvimento web e j trabalhou com as linguagens C, PHP, ASP, C#. Atualmente, ministra treinamentos, palestras e desenvolve solues com Python para web com os frameworks Pylons e web2py. um dos colaboradores do site web2pybrasil, e tambm vezes escreve tambm no blog http://rochacbruno.com.br. Alm dos projetos com Python, atua como desenvolvedor e coordenador de projetos (ScrumMaster) na empresa GENTE - http://servicogente.com.br Contato: http://twitter.com/rochacbruno - rochacbruno@gmail.com

lvaro Justen

@turicas
Graduando em Eng. de Telecomunicaes pela UFF, onde desenvolve atividades de pesquisa, ensino e extenso. desenvolvedor da Intelie e ativista de software livre h mais de 8 anos; colaborador no desenvolvimento do web2py; disseminador do Arduino e entusiasta de metodologias geis. Participante assduo de eventos e grupos de usurios, palestra e organiza eventos, como PythOnCampus, Arduino/web2py Hack Day e Dojorio. Escreve no blog http://blog.justen.eng.br Contato: http://twitter.com/turicas - alvarojusten@gmail.com

Autoria: Bruno Cezar Rocha Colaborao: lvaro Justen Reviso gramatical: Claudia P. Esta apostila contm partes traduzidas do livro oficial do web2py (http://web2py.com/book), esta traduo foi devidamente autorizada pelo autor do livro, Massimo di Pierro.

Desenvolvimento web com Python e web2py by Bruno Cezar Rocha is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike License. Based on a work at http://web2py.com Permissions beyond the scope of this license may be available at web2pybrasil.com.br.
[ http://www.web2pybrasil.com.br , http://www.temporealeventos.com.br ]

89