SlideShare uma empresa Scribd logo
Desenvolvimento Ágil de Aplicações Web com Python
                                                                       por Cláudio Torcato


terça-feira, 22 de novembro de 2011
terça-feira, 22 de novembro de 2011
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
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
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
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
Arquitetura: MVC




terça-feira, 22 de novembro de 2011
Arquitetura




terça-feira, 22 de novembro de 2011
Controller



terça-feira, 22 de novembro de 2011
Estrutura




terça-feira, 22 de novembro de 2011
Default.py




terça-feira, 22 de novembro de 2011
Roteamento de URL
                       http://localhost:8080/minicurso/default/index.html

                       padrão

                             init

                             default

                             index

                             html



terça-feira, 22 de novembro de 2011
Request
                       http://localhost:8000/a/c/f.html/x/y/z?p=1&q=2

                       request.args = [ 'x', 'y', 'z' ]

                       request.vars = { 'p' : 1, 'q' : 2 }

                       request.application = 'a'

                       request.controller = 'c'

                       request.function = 'f'



terça-feira, 22 de novembro de 2011
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
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
Response

              response.body

              response.cookies

              response.flash

              response.headers

              response.render(view, vars)

              response.view


terça-feira, 22 de novembro de 2011
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
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
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
View



terça-feira, 22 de novembro de 2011
Estrutura




terça-feira, 22 de novembro de 2011
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
Exemplos
                                      {{
                                      if request.args(0):
                                          response.write('existe')
                                      else:
                                          response.write('não existe')
                                      pass
                                      }}




terça-feira, 22 de novembro de 2011
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
{{=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
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
Exemplo de uso do Helper


                               {{=DIV(B(I('hello','<world>'))), _class="myclass") }}




                                      <div class="myclass">
                                        <b><i>hello &lt;world&gt;</i></b>
                                      </div>




terça-feira, 22 de novembro de 2011
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
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
Model



terça-feira, 22 de novembro de 2011
Estrutura




terça-feira, 22 de novembro de 2011
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
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
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
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
Tipos de Campos




terça-feira, 22 de novembro de 2011
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
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
Query


              Objeto que representa a cláusula “where” do SQL.

              query = (db.pessoas.nome == 'Alex')




terça-feira, 22 de novembro de 2011
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
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
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
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
Select: argumentos opcionais


              orderby

              groupby                 rows = db(db.pessoas)
                                        .select(orderby=db.pessoas.nome)
              limitby

              distinct




terça-feira, 22 de novembro de 2011
Operadores Lógicos

                rows = db((db.pessoas.nome == 'Alex') &
                  (db.pessoas.idade > 18)).select()

                rows = db((db.pessoas.nome == 'Alex') |
                  (db.pessoas.idade > 18)). select()

                rows = db(db.pessoas.nome != 'Alex').select()




terça-feira, 22 de novembro de 2011
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
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
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
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
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
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
Authentication


              Métodos de login:

                    tabela auth_user

                    Google, PAM, LDAP, Facebook, LinkedIn, OpenID, OAuth,
                    etc.




terça-feira, 22 de novembro de 2011
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
Forms

              FORM

              SQLFORM

              SQLFORM.factory

              CRUD




terça-feira, 22 de novembro de 2011
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
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
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
SQLFORM.factory




terça-feira, 22 de novembro de 2011
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
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
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
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
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
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
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
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
Service Decorator




terça-feira, 22 de novembro de 2011
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
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
Anúncio

Recomendados

Trabalhando com as views do Web2Py
Trabalhando com as views do Web2Py
Hugo Leonardo Costa e Silva
 
Java recursos avançados - socket connection
Java recursos avançados - socket connection
Armando Daniel
 
Java orientação a objetos (interfaces)
Java orientação a objetos (interfaces)
Armando Daniel
 
Java orientação a objetos (variaveis de instancia e metodos)
Java orientação a objetos (variaveis de instancia e metodos)
Armando Daniel
 
Design Patterns na Programação de Jogo
Design Patterns na Programação de Jogo
Bruno Cicanci
 
Java orientação a objetos (associacao, composicao, agregacao)
Java orientação a objetos (associacao, composicao, agregacao)
Armando Daniel
 
Dependency injection
Dependency injection
Guilherme Blanco
 
Clean Code e Object Calisthenics - Aplicados no PHP
Clean Code e Object Calisthenics - Aplicados no PHP
Rafael Neris
 
Combatendo code smells em aplicações Java
Combatendo code smells em aplicações Java
Emmanuel Neri
 
Java script aula 05 - funções
Java script aula 05 - funções
Cristiano Pires Martins
 
Vraptor
Vraptor
clauvane1708
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)
Pablo Dall'Oglio
 
Java introdução ao eclipse
Java introdução ao eclipse
Armando Daniel
 
Java script - funções
Java script - funções
Cristiano Pires Martins
 
Java script aula 02 - operadores
Java script aula 02 - operadores
Cristiano Pires Martins
 
Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6
Manuel Menezes de Sequeira
 
Solid
Solid
Jorge Oleques
 
[CLPE] Design patterns com c#
[CLPE] Design patterns com c#
Felipe Pimentel
 
FLTK Summer Course - Part II - Second Impact
FLTK Summer Course - Part II - Second Impact
Michel Alves
 
Java - Introdução a banco de dados
Java - Introdução a banco de dados
Sérgio Souza Costa
 
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Rogério Moraes de Carvalho
 
Java script aula 08 - formulários
Java script aula 08 - formulários
Cristiano Pires Martins
 
PHP 7
PHP 7
Guilherme Blanco
 
Java 06
Java 06
samuelthiago
 
Programação orientada a objetos em delphi
Programação orientada a objetos em delphi
Helder Lopes
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com Lombok
Wellington Pinheiro
 
Java introdução ao java
Java introdução ao java
Armando Daniel
 
Javascript
Javascript
Fernando Simeone
 
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Rodrigo Castardo
 
Plone e eGov: Presente e Futuro
Plone e eGov: Presente e Futuro
Simples Consultoria
 

Mais conteúdo relacionado

Mais procurados (20)

Combatendo code smells em aplicações Java
Combatendo code smells em aplicações Java
Emmanuel Neri
 
Java script aula 05 - funções
Java script aula 05 - funções
Cristiano Pires Martins
 
Vraptor
Vraptor
clauvane1708
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)
Pablo Dall'Oglio
 
Java introdução ao eclipse
Java introdução ao eclipse
Armando Daniel
 
Java script - funções
Java script - funções
Cristiano Pires Martins
 
Java script aula 02 - operadores
Java script aula 02 - operadores
Cristiano Pires Martins
 
Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6
Manuel Menezes de Sequeira
 
Solid
Solid
Jorge Oleques
 
[CLPE] Design patterns com c#
[CLPE] Design patterns com c#
Felipe Pimentel
 
FLTK Summer Course - Part II - Second Impact
FLTK Summer Course - Part II - Second Impact
Michel Alves
 
Java - Introdução a banco de dados
Java - Introdução a banco de dados
Sérgio Souza Costa
 
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Rogério Moraes de Carvalho
 
Java script aula 08 - formulários
Java script aula 08 - formulários
Cristiano Pires Martins
 
PHP 7
PHP 7
Guilherme Blanco
 
Java 06
Java 06
samuelthiago
 
Programação orientada a objetos em delphi
Programação orientada a objetos em delphi
Helder Lopes
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com Lombok
Wellington Pinheiro
 
Java introdução ao java
Java introdução ao java
Armando Daniel
 
Javascript
Javascript
Fernando Simeone
 
Combatendo code smells em aplicações Java
Combatendo code smells em aplicações Java
Emmanuel Neri
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)
Pablo Dall'Oglio
 
Java introdução ao eclipse
Java introdução ao eclipse
Armando Daniel
 
[CLPE] Design patterns com c#
[CLPE] Design patterns com c#
Felipe Pimentel
 
FLTK Summer Course - Part II - Second Impact
FLTK Summer Course - Part II - Second Impact
Michel Alves
 
Java - Introdução a banco de dados
Java - Introdução a banco de dados
Sérgio Souza Costa
 
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Rogério Moraes de Carvalho
 
Programação orientada a objetos em delphi
Programação orientada a objetos em delphi
Helder Lopes
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com Lombok
Wellington Pinheiro
 
Java introdução ao java
Java introdução ao java
Armando Daniel
 

Destaque (9)

Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Rodrigo Castardo
 
Plone e eGov: Presente e Futuro
Plone e eGov: Presente e Futuro
Simples Consultoria
 
Oficina Mergulhando no Plone 4
Oficina Mergulhando no Plone 4
Tania Andrea
 
Plone - Poderoso e flexível
Plone - Poderoso e flexível
Lucas Aquino
 
Otimizando Portais Plone: Dicas de Desempenho
Otimizando Portais Plone: Dicas de Desempenho
Douglas Soares de Andrade
 
Plone total#2 - Gerenciamento de conteúdos
Plone total#2 - Gerenciamento de conteúdos
Lucas Aquino
 
Canivete suíço do Python
Canivete suíço do Python
Douglas Soares de Andrade
 
Canivete python
Canivete python
Anderson Dantas
 
Desenvolvendo aplicações web com python e web2py
Desenvolvendo aplicações web com python e web2py
Gilson Filho
 
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Rodrigo Castardo
 
Oficina Mergulhando no Plone 4
Oficina Mergulhando no Plone 4
Tania Andrea
 
Plone - Poderoso e flexível
Plone - Poderoso e flexível
Lucas Aquino
 
Otimizando Portais Plone: Dicas de Desempenho
Otimizando Portais Plone: Dicas de Desempenho
Douglas Soares de Andrade
 
Plone total#2 - Gerenciamento de conteúdos
Plone total#2 - Gerenciamento de conteúdos
Lucas Aquino
 
Desenvolvendo aplicações web com python e web2py
Desenvolvendo aplicações web com python e web2py
Gilson Filho
 
Anúncio

Semelhante a Web2py: Desenvolvimento Ágil de Aplicações Web com Python (20)

Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011
Luciano Ramalho
 
Curso de Node JS Básico
Curso de Node JS Básico
Victor Hazin da Rocha
 
Workshop Django
Workshop Django
Sérgio Santos
 
Introdução ao jquery
Introdução ao jquery
Yuri Costa
 
Palestra cbq
Palestra cbq
Rildo Pragana
 
(Re)pensando a OOP - Flisol Gyn
(Re)pensando a OOP - Flisol Gyn
Luís Cobucci
 
Persistencia de dados em aplicações Android
Persistencia de dados em aplicações Android
Antonio Marin Neto
 
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Rogério Moraes de Carvalho
 
Otimizando aplicações Zend Framework - Tchelinux
Otimizando aplicações Zend Framework - Tchelinux
Elton Minetto
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)
Luciano Ramalho
 
Persistência de Dados no SQLite com Room
Persistência de Dados no SQLite com Room
Nelson Glauber Leal
 
FEUCTEC 2016 - Hub de eventos com redis
FEUCTEC 2016 - Hub de eventos com redis
Charles Lomboni
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHP
Guilherme Blanco
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
Régis Eduardo Weizenmann Gregol
 
Oficial
Oficial
Régis Eduardo Weizenmann Gregol
 
Desfrutando os Componentes do Zend Framework
Desfrutando os Componentes do Zend Framework
Fernando Geraldo Mantoan
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
Guilherme Blanco
 
Project coin pequenas mudanças grandes facilidades
Project coin pequenas mudanças grandes facilidades
Marcelo de Castro
 
Possibilidades com python
Possibilidades com python
UFPA
 
Otimizacao de aplicações Zend Framework
Otimizacao de aplicações Zend Framework
Elton Minetto
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011
Luciano Ramalho
 
Introdução ao jquery
Introdução ao jquery
Yuri Costa
 
(Re)pensando a OOP - Flisol Gyn
(Re)pensando a OOP - Flisol Gyn
Luís Cobucci
 
Persistencia de dados em aplicações Android
Persistencia de dados em aplicações Android
Antonio Marin Neto
 
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Rogério Moraes de Carvalho
 
Otimizando aplicações Zend Framework - Tchelinux
Otimizando aplicações Zend Framework - Tchelinux
Elton Minetto
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)
Luciano Ramalho
 
Persistência de Dados no SQLite com Room
Persistência de Dados no SQLite com Room
Nelson Glauber Leal
 
FEUCTEC 2016 - Hub de eventos com redis
FEUCTEC 2016 - Hub de eventos com redis
Charles Lomboni
 
Desfrutando os Componentes do Zend Framework
Desfrutando os Componentes do Zend Framework
Fernando Geraldo Mantoan
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
Guilherme Blanco
 
Project coin pequenas mudanças grandes facilidades
Project coin pequenas mudanças grandes facilidades
Marcelo de Castro
 
Possibilidades com python
Possibilidades com python
UFPA
 
Otimizacao de aplicações Zend Framework
Otimizacao de aplicações Zend Framework
Elton Minetto
 
Anúncio

Último (12)

SISTEMAS OPERACIONAIS DE COMPUTADORES PARTE 1
SISTEMAS OPERACIONAIS DE COMPUTADORES PARTE 1
jarlisonsantos1985
 
Joao Claudio Nunes Carvalho-Classificacao de filmes do Netflix.docx
Joao Claudio Nunes Carvalho-Classificacao de filmes do Netflix.docx
ssuser1712ed
 
Certified SAFe 6 Agilist
Certified SAFe 6 Agilist
Adail Viana Neto
 
Certified SAFe 6 Lean Portfolio Manager
Certified SAFe 6 Lean Portfolio Manager
Adail Viana Neto
 
POAN-1 trabalho de antena de microfita.pptx
POAN-1 trabalho de antena de microfita.pptx
joaquimpaulo2306
 
A-Historia-da-Programacao-Orientada-a-Objetos.pptx
A-Historia-da-Programacao-Orientada-a-Objetos.pptx
destruidorschirmer
 
Capítulo 7 - Redes de computadores multimídia.ppt
Capítulo 7 - Redes de computadores multimídia.ppt
ssuser0a4331
 
PPT - Capítulo 6 - Redes sem fio e redes móveis.ppt
PPT - Capítulo 6 - Redes sem fio e redes móveis.ppt
ssuser0a4331
 
Breve Histórico do Computador [2 de 2].pdf
Breve Histórico do Computador [2 de 2].pdf
jarlisonsantos1985
 
G.6 Avarias Mais Comuns em Computadores TIC2.pptx
G.6 Avarias Mais Comuns em Computadores TIC2.pptx
vieirapatricio94
 
Como Criar uma Partição Bootável no HD Interno.pptx
Como Criar uma Partição Bootável no HD Interno.pptx
vieirapatricio94
 
A-Historia-do-Java-Uma-Linguagem-que-Transformou-o-Cenario-da-Programacao.pptx
A-Historia-do-Java-Uma-Linguagem-que-Transformou-o-Cenario-da-Programacao.pptx
destruidorschirmer
 
SISTEMAS OPERACIONAIS DE COMPUTADORES PARTE 1
SISTEMAS OPERACIONAIS DE COMPUTADORES PARTE 1
jarlisonsantos1985
 
Joao Claudio Nunes Carvalho-Classificacao de filmes do Netflix.docx
Joao Claudio Nunes Carvalho-Classificacao de filmes do Netflix.docx
ssuser1712ed
 
Certified SAFe 6 Lean Portfolio Manager
Certified SAFe 6 Lean Portfolio Manager
Adail Viana Neto
 
POAN-1 trabalho de antena de microfita.pptx
POAN-1 trabalho de antena de microfita.pptx
joaquimpaulo2306
 
A-Historia-da-Programacao-Orientada-a-Objetos.pptx
A-Historia-da-Programacao-Orientada-a-Objetos.pptx
destruidorschirmer
 
Capítulo 7 - Redes de computadores multimídia.ppt
Capítulo 7 - Redes de computadores multimídia.ppt
ssuser0a4331
 
PPT - Capítulo 6 - Redes sem fio e redes móveis.ppt
PPT - Capítulo 6 - Redes sem fio e redes móveis.ppt
ssuser0a4331
 
Breve Histórico do Computador [2 de 2].pdf
Breve Histórico do Computador [2 de 2].pdf
jarlisonsantos1985
 
G.6 Avarias Mais Comuns em Computadores TIC2.pptx
G.6 Avarias Mais Comuns em Computadores TIC2.pptx
vieirapatricio94
 
Como Criar uma Partição Bootável no HD Interno.pptx
Como Criar uma Partição Bootável no HD Interno.pptx
vieirapatricio94
 
A-Historia-do-Java-Uma-Linguagem-que-Transformou-o-Cenario-da-Programacao.pptx
A-Historia-do-Java-Uma-Linguagem-que-Transformou-o-Cenario-da-Programacao.pptx
destruidorschirmer
 

Web2py: Desenvolvimento Ágil de Aplicações Web com Python

  • 1. Desenvolvimento Ágil de Aplicações Web com Python por Cláudio Torcato terça-feira, 22 de novembro de 2011
  • 2. terça-feira, 22 de novembro de 2011
  • 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
  • 7. Arquitetura: MVC terça-feira, 22 de novembro de 2011
  • 10. Estrutura terça-feira, 22 de novembro de 2011
  • 11. Default.py terça-feira, 22 de novembro de 2011
  • 12. Roteamento de URL http://localhost:8080/minicurso/default/index.html padrão init default index html terça-feira, 22 de novembro de 2011
  • 13. Request http://localhost:8000/a/c/f.html/x/y/z?p=1&q=2 request.args = [ 'x', 'y', 'z' ] request.vars = { 'p' : 1, 'q' : 2 } request.application = 'a' request.controller = 'c' request.function = 'f' 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
  • 20. View terça-feira, 22 de novembro de 2011
  • 21. Estrutura 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 &lt;world&gt;</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
  • 30. Model terça-feira, 22 de novembro de 2011
  • 31. Estrutura 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
  • 36. Tipos de Campos 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
  • 45. Operadores Lógicos rows = db((db.pessoas.nome == 'Alex') & (db.pessoas.idade > 18)).select() rows = db((db.pessoas.nome == 'Alex') | (db.pessoas.idade > 18)). select() rows = db(db.pessoas.nome != 'Alex').select() 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
  • 67. Service Decorator 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