O documento descreve o framework web Python Web2py. Resume as seguintes informações essenciais:
1) Web2py foi lançado em 2007 e tem como objetivos principais facilitar o uso, desenvolvimento rápido e segurança.
2) Web2py é inspirado em Ruby on Rails e Django, enfatizando desenvolvimento rápido e geradores de formulários.
3) Web2py oferece administração web baseada, interface MVC, sistema de ticketing e é open source.
3. História
Lançada em 2007
Massimo di Pierro, professor da Universidade DePaul,
Chicago
Objetivos principais:
Fácil uso, desenvolvimento rápido e segurança
Versão atual: 1.99.2 (26.09.11)
terça-feira, 22 de novembro de 2011
4. Inspirações
Ruby on Rails
Desenvolvimento rápido
MVC Design
Django
Geração de formulários a partir de tabelas do banco de
dados
Coleção de validadores extensíveis
terça-feira, 22 de novembro de 2011
5. Características
Sem necessidade de instalação e configuração
Interface Web para Manutenção, Deployment e
Desenvolvimento
Sistema de Ticketing
Framework Full-Stack
Retrocompatibilidade garantida
Open Source
terça-feira, 22 de novembro de 2011
6. Administração Web Based
Gerenciar aplicações
Criar aplicações
Desenvolver aplicações
Testar e Debugar
Integração com Mercurial
terça-feira, 22 de novembro de 2011
14. Usando Request
def variaveis():
vars = request.vars
args = request.args
return dict(vars = vars, args = args)
def primeiro_argumento():
variavel = request.args(0)
return dict(var=variavel)
terça-feira, 22 de novembro de 2011
15. Session
def contador():
if session.cont: session.cont = session.cont+1
else: session.cont = 1
return dict( contador = session.cont )
session.variavel = "Oinc"
session.forget()
session.connect(request, response, db, masterapp=None)
terça-feira, 22 de novembro de 2011
16. Response
response.body
response.cookies
response.flash
response.headers
response.render(view, vars)
response.view
terça-feira, 22 de novembro de 2011
17. URL
URL('f') -- /[application]/[controller]/f
Suporte a mapeamento de URL e mapeamento reverso
Redefine o mapeamento de URLs externas
URL('a', 'c', 'f', args=['x', 'y'], vars={ z : 't' })
terça-feira, 22 de novembro de 2011
18. HTTP and Redirect
raise HTTP(400, "mensagem de erro")
redirect('http://www.web2py.com')
redirect(URL('index', args=(1,2,3),vars=dict(a='b')))
terça-feira, 22 de novembro de 2011
19. i18n e l10n
Arquivos de linguagem
O objeto T é uma instância global do tradutor de
linguagem
Constantes String deveriam ser marcadas por T
Exemplo: T("Hello World")
terça-feira, 22 de novembro de 2011
22. Template Language
Python embutido em HTML
Código python entre {{ }}
Sem restrições à linguagem
Blocos de código finalizados por pass
terça-feira, 22 de novembro de 2011
23. Exemplos
{{
if request.args(0):
response.write('existe')
else:
response.write('não existe')
pass
}}
terça-feira, 22 de novembro de 2011
24. Geração da View
<html><body>
{{ for x in range(10):}}
{{=x}}hello<br/>
{{ pass }}
</body></html>
response.write("<html><body>", escape=False)
for x in range(10):
response.write(x)
response.write("hello<br/>", escape=False)
response.write("</body></html>", escape=False)
terça-feira, 22 de novembro de 2011
25. {{=variavel}}
response.write(x, escape=True)
Escaped por padrão
Se o objeto tem o método .xml(), ele é chamado e o escaping é
ignorado
Senão usa o método __str__ para serializar
terça-feira, 22 de novembro de 2011
26. HTML Helpers
Classes usadas para construir HTML programaticamente
Helpers: A, B, BEAUTIFY, BR, CENTER, CODE, DIV, EM,
EMBED, FIELDSET, FORM, H1, H2, H3, H4, H5, H6, HEAD,
HR, I, IFRAME, IMG, INPUT, LABEL, LEGEND, LI, LINK,
OL, UL, MARKMIN, MENU, META, OBJETCT, ON,
OPTION, P, PRE, etc.
terça-feira, 22 de novembro de 2011
27. Exemplo de uso do Helper
{{=DIV(B(I('hello','<world>'))), _class="myclass") }}
<div class="myclass">
<b><i>hello <world></i></b>
</div>
terça-feira, 22 de novembro de 2011
28. Page Layout
layout.html
<html><head><title>Page Title</title></head>
<body>
{{include}}
</body>
</html>
{{extend 'layout.html'}}
index.html
<h1>Hello World</h1>
{{include 'page.html'}}
terça-feira, 22 de novembro de 2011
29. Exemplo
controllers/visao.py
def lista():
return dict(numeros = range(30))
<ul>
views/visao/lista.html
{{ for numero in numeros: }}
<li> {{=numero }} </li>
{{ pass }}
</ul>
terça-feira, 22 de novembro de 2011
32. Responsabilidades do Model
Acessar o Banco
Mapear Objetos e Tabelas
Gerar SQL dinamicamente
Validar campos das tabelas e formulários
terça-feira, 22 de novembro de 2011
33. Database Abstraction Layer - DAL
“An API that maps Python objects into database objects such
as queries, tables, and records.”
Adapdadores para cada dialeto SQL
db = DAL("string de conexão")
terça-feira, 22 de novembro de 2011
34. String de Conexão
SQLite sqlite://storage.db
MySQL mysql://username:password@localhost/
PostgreSQL postgres://username:pass@localhost/test
test
MSSQL mssql://username:pass@localhost/test
Firebird firebird://username:pass@localhost/test
Oracle oracle://username/pass@test
DB2 db2://username:pass@test
Ingres ingres://username:pass@localhost/test
Informix informix://username:pass@test
Google App
gae
Engine
terça-feira, 22 de novembro de 2011
35. Table
db.define_table('pessoas',
Field('nome'),
Field('casado','boolean',default=False),
Field('genero'),
Field('data_nascimento','date',label='Data de Nascimento')
)
db.pessoas.genero.requires = IS_IN_SET(['M','F','?'])
terça-feira, 22 de novembro de 2011
37. Migrations
Alterações na definição de uma tabela no DAL refletirá
no banco de dados
Tais mudanças são registradas em logs
db = DAL('sqlite://storage.db', migrate = False)
terça-feira, 22 de novembro de 2011
38. Métodos de Table
db.pessoas.insert(nome='Helena')
db.pessoas.truncate()
db.pessoas.bulk_insert({'nome':'Ana','sexo':'F'})
terça-feira, 22 de novembro de 2011
39. Query
Objeto que representa a cláusula “where” do SQL.
query = (db.pessoas.nome == 'Alex')
terça-feira, 22 de novembro de 2011
40. Set
Representa um conjunto de registros
Alguns métodos: count, select, update, delete
Exemplo: meu_set = db(query)
rows = meu_set.select()
meu_set.update(nome='Eloah')
meu_set.delete()
terça-feira, 22 de novembro de 2011
41. Rows
Resultado do comando select
class gluon.sql.Rows
Objeto iterável cujos elementos são objetos Row
(gluon.sql.Row)
Objetos Row são parecidos com dicionários mas seus
elementos podem ser acessados como atributos
terça-feira, 22 de novembro de 2011
42. Exemplo de Rows e Row
controller def solteiros():
query = (db.pessoas.casado == False)
linhas = db(query).select()
return dict( linhas = linhas)
view <h2>Lista de Solteiros</h2>
<ul>
{{ for solteiro in linhas: }} solteiro['nome']
<li> {{=solteiro.nome }} solteiro('pessoas.nome')
{{ pass }}
</ul>
terça-feira, 22 de novembro de 2011
43. Selects Recursivos
db.define_table('caes',
Field('nome'),
Field('dono', db.pessoas))
caes = db(db.caes).select()
for cao in caes:
print 'Nome do Dono:', cao.dono.nome
terça-feira, 22 de novembro de 2011
44. Select: argumentos opcionais
orderby
groupby rows = db(db.pessoas)
.select(orderby=db.pessoas.nome)
limitby
distinct
terça-feira, 22 de novembro de 2011
46. Campos Computados
from datetime import date
def idade(tabela):
niver = tabela.data_nascimento
hoje = date.today()
return niver.year - hoje.year
db.define_table('pessoas',
Field('nome'),
Field('data_nascimento','date'),
Field('idade', compute = idade))
terça-feira, 22 de novembro de 2011
47. Campos Virtuais
Não alocados no BD
Computados a cada consulta no banco
class VirtualPessoa(object):
def idade(self):
return date.today().year -
self.pessoas.data_nascimento.year
db.pessoas.virtualfields.append(VirtualPessoa())
terça-feira, 22 de novembro de 2011
48. Update
db.pessoas[ 2 ]
db(db.pessoas.id == 2).select().first()
obj = db.pessoas(2)
obj.update_record(nome='Edna')
db(db.pessoas.data_nascimento.year() > 1990).
update(db.pessoas.cidade_natal = 'Teresina')
terça-feira, 22 de novembro de 2011
49. Joins
Inner Join
db(db.pessoas.id == db.caes.dono).select()
Left Outer Join
db().select(db.pessoas.ALL, db.caes.ALL,
left=db.caes.on(db.pessoas.id==db.caes.dono))
terça-feira, 22 de novembro de 2011
50. Visualizando o SQL
print db.pessoas._insert(nome='Daniel')
print db(db.pessoas)._count()
print db(db.pessoas.idade < 19)._select()
print db(db.pessoas.idade == 20)._delete()
print db(db.pessoas.idade == 20)._update()
terça-feira, 22 de novembro de 2011
51. Auth
Role Based Access Control (RBAC)
Auth implementa RBAC
Tabelas:
auth_user, auth_group, auth_membership,
auth_permission, auth_event
Decorators são usados para restringir acesso a funções por
login, membership ou permissions
terça-feira, 22 de novembro de 2011
52. Authentication
Métodos de login:
tabela auth_user
Google, PAM, LDAP, Facebook, LinkedIn, OpenID, OAuth,
etc.
terça-feira, 22 de novembro de 2011
53. Auth Decorators
@auth.requires_login()
def function_um():
return "requer login"
@auth.requires_membership("agentes")
def function_dois():
return "você é um agente"
@auth.requires_permission('read', db.documentos)
def function_tres():
return "você pode ler documentos secretos"
terça-feira, 22 de novembro de 2011
54. Forms
FORM
SQLFORM
SQLFORM.factory
CRUD
terça-feira, 22 de novembro de 2011
55. FORM
def formulario():
form = FORM('Seu nome:',
INPUT(_name='nome'),
INPUT(_type='submit'))
return dict(form=form)
{{=form}}
terça-feira, 22 de novembro de 2011
56. FORM
Validação e processamento do Formulário
def formulario2():
form=FORM('Seu nome:',
INPUT(_name='nome',
requires=IS_NOT_EMPTY()),
INPUT(_type='submit'))
if form.process().accepted:
response.flash = 'formulário aceito'
elif form.errors:
response.flash = 'formulário tem erros'
else:
response.flash = 'preencha o formulário'
return dict(form=form)
terça-feira, 22 de novembro de 2011
57. SQLFORM
def formulario():
form = SQLFORM(db.pessoas)
if form.process().accepted:
response.flash = 'form aceito.'
elif form.errors:
response.flash = 'form tem erro.'
else:
response.flash = 'preencha form.'
return dict(form=form)
terça-feira, 22 de novembro de 2011
59. CRUD
from gluon.tools import Crud
crud = Crud(db)
API recente
Simplifica o uso do SQLFORM por incorporar diversas
atividades numa única função
Precisa ser importada
Deve ser ligada a um banco de dados
terça-feira, 22 de novembro de 2011
60. Métodos CRUD
crud.tables()
crud.create(db.nome_tabela)
crud.read(db.nome_tabela, id)
crud.update(db.nome_tabela, id)
crud.delete(db.nome_tabela, id)
crud.select(db.nome_tabela, query)
crud.search(db.nome_tabela)
crud()
terça-feira, 22 de novembro de 2011
61. Funções com CRUD
def create_cao():
form = crud.create(db.caes)
return dict(form = form)
def update_cao():
form = crud.update(db.caes, request.args(0))
return dict(form = form)
terça-feira, 22 de novembro de 2011
62. Validadores
Classes usadas para validar entrada de campos (incluindo
forms gerados de tabelas)
Podem ser usadas em Fields e em Forms
Sempre atribuídos usando o atributo requires de um campo
terça-feira, 22 de novembro de 2011
63. Lista de Validadores
IS_ALPHANUMERIC, IS_DATE, IS_DATE_IN_RANGE,
IS_DATETIME, IS_DATETIME_IN_RANGE,
IS_DECIMAL_IN_RANGE, IS_EMAIL, IS_EXPR,
IS_FLOAT_IN_RANGE, IS_IN_SET, IS_LENGTH,
IS_LIST_OF, IS_LOWER, IS_URL, IS_STRONG,
IS_EMPTY_OR, CLEANUP, CRYPT
terça-feira, 22 de novembro de 2011
64. Services
Sistema de software projetado para suportar a interação
máquina-máquina numa rede
Suporte a XML, JSON, RSS, CSV, XMLRPC, JSONRPC,
AMFRPC e SOAP
Modos de suporte:
Renderizar a saída de uma função
Remote Procedure Calls
terça-feira, 22 de novembro de 2011
65. Generic Views
default/contador.xml procura views/default/contador.xml
Não encontrando, procura views/default/generic.xml
Generics para JSON, PDF, RSS, XML
terça-feira, 22 de novembro de 2011
66. Remote Procedure Calls
Web2py prover mecanismo para tornar qualquer função um
web service
O que precisamos:
instanciar o objeto service
expor um manipulador de serviços no controller
decorar a função que será exposta como um serviço
terça-feira, 22 de novembro de 2011
68. Do que não falamos
URL Rewrite Central Authentication
Service
Roteamento de Erros
jQuery e Ajax
Tarefas em background
Deploy em Servidores de
Pyjamas
Produção
Blocks in Views
Escalabidade
Caching
Google App Engine
Exportação e Importação de
Componentes e Plugins
Dados
terça-feira, 22 de novembro de 2011
69. Referências
Web2py: http://www.web2py.com
web2py-users-brazil: https://groups.google.com/group/
web2py-users-brazil?hl=pt-BR
The Official Web2py Book: http://www.web2py.com/book
http://www.infoworld.com/d/application-development/
pillars-python-six-python-web-frameworks-compared-169442
terça-feira, 22 de novembro de 2011