SlideShare ist ein Scribd-Unternehmen logo
1 von 69
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

Combatendo code smells em aplicações Java
Combatendo code smells em aplicações JavaCombatendo code smells em aplicações Java
Combatendo code smells em aplicações JavaEmmanuel Neri
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)As novidades do PHP5 (2005)
As novidades do PHP5 (2005)Pablo Dall'Oglio
 
Java introdução ao eclipse
Java   introdução ao eclipseJava   introdução ao eclipse
Java introdução ao eclipseArmando Daniel
 
[CLPE] Design patterns com c#
[CLPE] Design patterns com c#[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 ImpactFLTK Summer Course - Part II - Second Impact
FLTK Summer Course - Part II - Second ImpactMichel Alves
 
Java - Introdução a banco de dados
Java - Introdução a banco de dadosJava - Introdução a banco de dados
Java - Introdução a banco de dadosSé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# 7Plataforma de compiladores .NET,Visual Studio 2015, C# 6 e futuro C# 7
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7Rogério Moraes de Carvalho
 
Programação orientada a objetos em delphi
Programação orientada a objetos em delphiProgramação orientada a objetos em delphi
Programação orientada a objetos em delphiHelder Lopes
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com LombokReduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com LombokWellington Pinheiro
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao javaArmando Daniel
 

Was ist angesagt? (20)

Combatendo code smells em aplicações Java
Combatendo code smells em aplicações JavaCombatendo code smells em aplicações Java
Combatendo code smells em aplicações Java
 
Java script aula 05 - funções
Java script   aula 05 - funçõesJava script   aula 05 - funções
Java script aula 05 - funções
 
Vraptor
VraptorVraptor
Vraptor
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)As novidades do PHP5 (2005)
As novidades do PHP5 (2005)
 
Java introdução ao eclipse
Java   introdução ao eclipseJava   introdução ao eclipse
Java introdução ao eclipse
 
Java script - funções
Java script - funçõesJava script - funções
Java script - funções
 
Java script aula 02 - operadores
Java script   aula 02 - operadoresJava script   aula 02 - operadores
Java script aula 02 - operadores
 
Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6
 
Solid
SolidSolid
Solid
 
[CLPE] Design patterns com c#
[CLPE] Design patterns com c#[CLPE] Design patterns com c#
[CLPE] Design patterns com c#
 
FLTK Summer Course - Part II - Second Impact
FLTK Summer Course - Part II - Second ImpactFLTK Summer Course - Part II - Second Impact
FLTK Summer Course - Part II - Second Impact
 
Java - Introdução a banco de dados
Java - Introdução a banco de dadosJava - Introdução a banco de dados
Java - Introdução a banco de dados
 
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# 7Plataforma 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
 
Java script aula 08 - formulários
Java script   aula 08 - formuláriosJava script   aula 08 - formulários
Java script aula 08 - formulários
 
PHP 7
PHP 7PHP 7
PHP 7
 
Java 06
Java 06Java 06
Java 06
 
Programação orientada a objetos em delphi
Programação orientada a objetos em delphiProgramação orientada a objetos em delphi
Programação orientada a objetos em delphi
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com LombokReduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com Lombok
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
 
Javascript
JavascriptJavascript
Javascript
 

Andere mochten auch

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 DiazoComo 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 DiazoRodrigo Castardo
 
Oficina Mergulhando no Plone 4
Oficina Mergulhando no Plone 4Oficina Mergulhando no Plone 4
Oficina Mergulhando no Plone 4Tania Andrea
 
Plone - Poderoso e flexível
Plone - Poderoso e flexívelPlone - Poderoso e flexível
Plone - Poderoso e flexívelLucas Aquino
 
Otimizando Portais Plone: Dicas de Desempenho
Otimizando Portais Plone: Dicas de DesempenhoOtimizando Portais Plone: Dicas de Desempenho
Otimizando Portais Plone: Dicas de DesempenhoDouglas Soares de Andrade
 
Plone total#2 - Gerenciamento de conteúdos
Plone total#2 - Gerenciamento de conteúdosPlone total#2 - Gerenciamento de conteúdos
Plone total#2 - Gerenciamento de conteúdosLucas Aquino
 
Desenvolvendo aplicações web com python e web2py
Desenvolvendo aplicações web com python e web2pyDesenvolvendo aplicações web com python e web2py
Desenvolvendo aplicações web com python e web2pyGilson Filho
 

Andere mochten auch (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 DiazoComo 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
 
Plone e eGov: Presente e Futuro
Plone e eGov: Presente e FuturoPlone e eGov: Presente e Futuro
Plone e eGov: Presente e Futuro
 
Oficina Mergulhando no Plone 4
Oficina Mergulhando no Plone 4Oficina Mergulhando no Plone 4
Oficina Mergulhando no Plone 4
 
Plone - Poderoso e flexível
Plone - Poderoso e flexívelPlone - Poderoso e flexível
Plone - Poderoso e flexível
 
Otimizando Portais Plone: Dicas de Desempenho
Otimizando Portais Plone: Dicas de DesempenhoOtimizando Portais Plone: Dicas de Desempenho
Otimizando Portais Plone: Dicas de Desempenho
 
Plone total#2 - Gerenciamento de conteúdos
Plone total#2 - Gerenciamento de conteúdosPlone total#2 - Gerenciamento de conteúdos
Plone total#2 - Gerenciamento de conteúdos
 
Canivete suíço do Python
Canivete suíço do PythonCanivete suíço do Python
Canivete suíço do Python
 
Canivete python
Canivete pythonCanivete python
Canivete python
 
Desenvolvendo aplicações web com python e web2py
Desenvolvendo aplicações web com python e web2pyDesenvolvendo aplicações web com python e web2py
Desenvolvendo aplicações web com python e web2py
 

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

Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Luciano Ramalho
 
Introdução ao jquery
Introdução ao jqueryIntrodução ao jquery
Introdução ao jqueryYuri Costa
 
(Re)pensando a OOP - Flisol Gyn
(Re)pensando a OOP - Flisol Gyn(Re)pensando a OOP - Flisol Gyn
(Re)pensando a OOP - Flisol GynLuís Cobucci
 
Persistencia de dados em aplicações Android
Persistencia de dados em aplicações AndroidPersistencia de dados em aplicações Android
Persistencia de dados em aplicações AndroidAntonio Marin Neto
 
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuroVisual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuroRogério Moraes de Carvalho
 
Otimizando aplicações Zend Framework - Tchelinux
Otimizando aplicações Zend Framework - TchelinuxOtimizando aplicações Zend Framework - Tchelinux
Otimizando aplicações Zend Framework - TchelinuxElton Minetto
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)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 RoomPersistência de Dados no SQLite com Room
Persistência de Dados no SQLite com RoomNelson Glauber Leal
 
FEUCTEC 2016 - Hub de eventos com redis
FEUCTEC 2016 - Hub de eventos com redisFEUCTEC 2016 - Hub de eventos com redis
FEUCTEC 2016 - Hub de eventos com redisCharles Lomboni
 
Desfrutando os Componentes do Zend Framework
Desfrutando os Componentes do Zend FrameworkDesfrutando os Componentes do Zend Framework
Desfrutando os Componentes do Zend FrameworkFernando Geraldo Mantoan
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmGuilherme Blanco
 
Project coin pequenas mudanças grandes facilidades
Project coin pequenas mudanças grandes facilidadesProject coin pequenas mudanças grandes facilidades
Project coin pequenas mudanças grandes facilidadesMarcelo de Castro
 
Possibilidades com python
Possibilidades com pythonPossibilidades com python
Possibilidades com pythonUFPA
 
Otimizacao de aplicações Zend Framework
Otimizacao de aplicações Zend FrameworkOtimizacao de aplicações Zend Framework
Otimizacao de aplicações Zend FrameworkElton Minetto
 

Ähnlich wie Web2py: Desenvolvimento Ágil de Aplicações Web com Python (20)

Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011
 
Curso de Node JS Básico
Curso de Node JS BásicoCurso de Node JS Básico
Curso de Node JS Básico
 
Workshop Django
Workshop DjangoWorkshop Django
Workshop Django
 
Introdução ao jquery
Introdução ao jqueryIntrodução ao jquery
Introdução ao jquery
 
Palestra cbq
Palestra cbqPalestra cbq
Palestra cbq
 
(Re)pensando a OOP - Flisol Gyn
(Re)pensando a OOP - Flisol Gyn(Re)pensando a OOP - Flisol Gyn
(Re)pensando a OOP - Flisol Gyn
 
Persistencia de dados em aplicações Android
Persistencia de dados em aplicações AndroidPersistencia de dados em aplicações Android
Persistencia de dados em aplicações Android
 
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuroVisual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
 
Otimizando aplicações Zend Framework - Tchelinux
Otimizando aplicações Zend Framework - TchelinuxOtimizando aplicações Zend Framework - Tchelinux
Otimizando aplicações Zend Framework - Tchelinux
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)
 
Persistência de Dados no SQLite com Room
Persistência de Dados no SQLite com RoomPersistência de Dados no SQLite com Room
Persistência de Dados no SQLite com Room
 
FEUCTEC 2016 - Hub de eventos com redis
FEUCTEC 2016 - Hub de eventos com redisFEUCTEC 2016 - Hub de eventos com redis
FEUCTEC 2016 - Hub de eventos com redis
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
 
Oficial
OficialOficial
Oficial
 
Desfrutando os Componentes do Zend Framework
Desfrutando os Componentes do Zend FrameworkDesfrutando os Componentes do Zend Framework
Desfrutando os Componentes do Zend Framework
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
 
Project coin pequenas mudanças grandes facilidades
Project coin pequenas mudanças grandes facilidadesProject coin pequenas mudanças grandes facilidades
Project coin pequenas mudanças grandes facilidades
 
Possibilidades com python
Possibilidades com pythonPossibilidades com python
Possibilidades com python
 
Otimizacao de aplicações Zend Framework
Otimizacao de aplicações Zend FrameworkOtimizacao de aplicações Zend Framework
Otimizacao de aplicações Zend Framework
 

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