Upload
martin-mulone
View
5.050
Download
13
Embed Size (px)
DESCRIPTION
Presentación de la Pycon Argentina 2011 sobre el web2py.
Citation preview
Pensando en grande
Por Martín MuloneNivel: Intermedio@mulonemartin
Principales características del framework
Utiliza el patrón de diseño MVC
Corre en todos lados (escrito en lenguaje Python): Win, Linux, Mac.
No tiene archivos de configuración y ninguna otra dependencia más que el python estándar.
Tiene integrado una capa de abstracción de datos. Escribe el SQL por nosotros en tiempo real. Soporta Sqlite, Appengine, Postgresql, Mysql, Oracle, DB2, Mssql, Informix, etc.
Código libre y desarrollado por una comunidad. LGPL v3.0
La seguridad como primera prioridad
No requiere instalación. Soporte PyPI
Siempre compatible con versiones anteriores
Web forms, Validators, Uploads, Helpers, Autorizaciones, Roles, etc.
Administración de aplicaciones, errores y tickets en linea. Ayuda de creación de aplicaciones: Wizard.
Web2py: Logros obtenidos
“Web2py Framework - Bossie Awards 2011. The best open source application development software. InfoWorld's Test Center picks the best open source development tools of 2011. By Doug Dineley, Peter Wayner,
Rick Grehan InfoWorld.com
“Web2py score: 8.8 Very Good. Infoworld.com "Web2py may well be the best framework for Python-savvy developers to enter the world of framework-based Web application development." Rick Grehan in "Pillars of Python: Six Python Web frameworks compared" Infoworld.com
3000 Usuarios registrados en los diferentes grupos. Siendo una comunidad muy activa y participativa.
Más de 50 desarrolladores han colaborado en el proyecto desde 2007.
Aplicaciones del usuario
Arquitectura de aplicaciones del usuario - Modelos
Models
Controllers
Views
Translations
Static Files
Modules
db = DAL('sqlite://storage.sqlite') db.define_table('clientes', Field('nombre','string'), Field('apellido','string'))
db.define_table('productos', Field('nombre','string'), Field('categoria','string'))
Models
db.pymenu.py
Arquitectura de aplicaciones del usuario - Controladores
Models
Controllers
Views
Translations
Static Files
Modules
def agregar_cliente(): form = SQLFORM(db.clientes) if form.process().accepted: response.flash = 'cliente agregado!' return dict(form=form)
def agregar_productos(): form = SQLFORM(db.productos) if form.process().accepted: response.flash = 'producto agregado!' return dict(form=form)
Controllers
default.py
Arquitectura de aplicaciones del usuario - Vistas
Models
Controllers
Views
Translations
Static Files
Modules
{{extend 'layout.html'}}{{=form}}
Views
default
agregar_producto.htmlagregar_cliente.html
layout.html
agregar_producto.html
{{extend 'layout.html'}}{{=form}}
agregar_cliente.html
layout.html
<html><body>{{include}}</body></html>
Agregar Cliente Agregar Producto
http://localhost:8000/default/agregar_cliente http://localhost:8000/default/agregar_producto
Modelsdb.pymenu.py
request request
Server
agregar_cliente agregar_producto
controllercontroller
view view
browser browser
layout.html
Diagrama de funcionamiento de nuestra aplicación
Agregar Cliente Agregar Producto
http://localhost:8000/default/agregar_cliente http://localhost:8000/default/agregar_producto
Modelsclientes.pydb.pyfacturacion.pyformularios.pymenu.pyproductos.pyventas.pysettings.py
request request
Server
Diagrama de funcionamiento de nuestra applicación + cant. modelos
A medida que nuestra aplicación incrementa la cantidad de modelos, decrece el rendimiento.
Polución del espacio de nombres “namespace” a través de los modelos.
Orden de ejecución de modelos.
Problemáticas que acontecen con muchos modelos
:(
clientes.pydb.pyfacturacion.pyformularios.pymenu.pyproductos.pyventas.pysettings.py
Se leen todos los archivos .py de la carpeta “models” de manera secuencial y en orden alfabético.
Models
01_settings.py02_db.py03_menu.py04_clientes.py05_facturacion.py06_productos.py07_formularios.py08_ventas.py
Models
Se deben renombrar los archivos anteponiendo números, para darle orden a la lógica de ejecución de nuestros modelos. Ejemplo: No podemos definir nuestros datos si antes no conectamos a nuestra base de datos.
Orden de ejecución de los modelos
clientes.pydb.pyfacturacion.pyformularios.pymenu.pyproductos.pyventas.pysettings.py
models models
clientes
01_db.py02_menu.py03_clientes.py
productos
01_db.py02_menu.py03_productos.py
Carpetas con el nombre del controlador, hace que en el “request” sólo sea tenido en cuenta los modelos que se encuentren en la carpeta correspondiente al controlador pedido.
Mejor aún
Uso de modelos condicionales
Modules/__init__.pyclientes.pyfacturacion.pyproductos.py
Uso de módulos
Models
Controllers
Views
Translations
Static Files
Modules
Basta con poner nuestros archivos .py en la carpeta modules/ que contengan nuestras librerías con clases, objetos, etc. que queremos usar en nuestras aplicaciones.
Luego hacemos uso de los mismos haciendo “import” desde nuestros controladores o modelos.
ANTES
modules__init__.pyclientes.py
modules__init__.pyclientes.py
modclientes = local_import(“clientes”)clientes = modclientes.Clientes()
AHORA
from clientes import Clientesclientes = Clientes()
Uso de módulos
Modules/clientes.py
from gluon import *
class Clientes(object): """ Métodos de cliente """ def __init__(self, db): self.db = db
def define_tables(self): db = self.db db.define_table('clientes', Field('nombre','string'), Field('apellido','string'))
def listar(self): db = self.db return db(db.clientes>0).select()
Models/db.py
Controllers/clientes.py
from clientes import Clientes
def listar(): “”” Lista los Clientes “”” clientes = Clientes(db) clientes.define_tables() lista = clientes.listar()
return dict(lista=lista)
Ejemplo 1 - Uso de módulos
db = DAL('sqlite://storage.sqlite')
Modules/miapp.pyclientes.py
from gluon import *
class MiApp(object): def __init__(self, db): self.db = db
def define_tables(self): db = self.db db.define_table('clientes', Field('nombre','string'), Field('apellido','string'))
db.define_table('productos', Field('nombre','string'), Field('categoria','string'))
Models/db.py
Controllers/clientes.py
from clientes import Clientes
def listar(): “”” Lista los Clientes “”” clientes = Clientes(db) app = MiApp(db) app.define_tables() lista = clientes.listar()
return dict(lista=lista)
Ejemplo 2 - Uso de módulos
db = DAL('sqlite://storage.sqlite')
Usando módulos en nuestro ambiente de desarrollo
if request.is_local: from gluon.custom_import import track_changes track_changes()
Para cada cambio en nuestros módulos habría que reiniciar el web2py, para evitar esta práctica lo que hacemos es agregar al comienzo de nuestro primer modelo las siguientes lineas:
Módulos: Accediendo a las variables globales: request, response, etc.
Modules/miapp.py
from gluon import *
class MiApp(object): def __init__(self, db): self.db = db response = current.response request = current.request session = current.session
Para acceder a las variables globales request, response, session y otras ayudas de web2py basta con hacer en nuestro módulo “from gluon import *” esto nos trae:
● El objeto thread local current : response, request, session. ● Ayudas: H1, A, SPAN, TAG, etc.● Validadores: IS_IN_DB, IS_IMAGE, etc.● Otros: DAL, SQLFORM, SQLTABLE, etc.
Cuando es necesario un uso obligatorio de módulos
Desarrollo de plugins, extensiones u otros agregados. Dichas extensiones no deben mezclarse con la lógica principal de nuestra aplicación en desarrollo. Se hace uso de las mismas importándolas en nuestra aplicación.
Desarrollo de “plugins”
modules
plugins
comments.py
from gluon import *
class PluginComments(object): def __init__(self, db): self.db = db
def install(self): db = self.db db.define_table('comments', Field('record','integer'), Field('author_id', db.auth_user), Field('comment','text')) return self
def render(self, record): db = self.db return db(db.comments.record==record).select()
Controllers/clientes.py
from clientes import Clientesfrom plugins.comments import PluginComments
def cliente(): cli = request.vars.id clientes = Clientes(db) info = clientes.info(cli) comenta = PluginComments(db).install().render(cli)
return dict(info=info, comenta=comenta)
EVITARcontrollers
default.pycontrollers
clientes.pyproductos.py
def agregar_cliente(): return dict()
def agregar_producto(): return dict()
HACER
Prácticas en el uso de controladores
clientes.py def agregar(): return dict()
productos.py def agregar(): return dict()
http://localhost:8000/default/agregar_clientehttp://localhost:8000/default/agregar_producto
http://localhost:8000/clientes/agregarhttp://localhost:8000/productos/agregar
Mágia
“The important thing is to have just the right amount of magic.” Michael Foord.
El desarrollo moderno, es muy competitivo, requiere que las soluciones se desarrollen en el menor tiempo posible para abaratar costos.
Un ejemplo de administración de usuarios:
usuarios = SQLFORM.grid(db.auth_user)
El framework nos brinda ciertas herramientas que nos permiten simplificar el desarrollo a una manera muy sencilla, pero no única.
Nuevo CRUD: Grid y Smartgrid
Nos permite hacer Altas, Bajas, Modificaciones, Búsquedas, Exportar a CSV. Soporta Paginación, Ordenar por campo, tablas referenciadas y más.
db.define_table('person',Field('name'))db.define_table('dog',Field('name'),Field('image','upload'),Field('owner',db.person))db.dog.owner.requires = IS_IN_DB(db, 'person.id', db.person._format)
@auth.requires_login()def smartgrid(): grid=SQLFORM.smartgrid(db.person) return dict(grid=grid)
controllers/default.py
models/db.py
Scheduler
Nos permite correr tareas diferidas y/o programadas.
No tiene requerimientos de librerías, usa el propio DAL para llevar la cola de tareas.
Ideal para tareas largas en ejecución.
Tareas programadas: diarias, semanales, mensuales, etc.
Utiliza la notación JSON, para pasar las variables.
Sencillo y liviano sólo 400 líneas de código.
Corre en segundo plano, por lo que no está afectado por los “timeouts” de navegadores.
Scheduler ejemplo
Aplicación completa: http://bit.ly/qmHk1m
modelsdb.pytasks.py
from gluon.scheduler import Scheduler
def populate_db(): from gluon.contrib.populate import populate populate(db.person,200) populate(db.dog,200) db.commit() #list your task hereavailable_tasks = dict(populate_db=populate_db)
scheduler = Scheduler(db, available_tasks)modules
plugins
scheduler.py
scheduler from gluon.scheduler import Scheduler if __name__ == "__main__": """ Main execution """ scheduler.loop()
Correr scheduler como:
python web2py.py --port=8001 -S scheduler -M -R applications/scheduler/modules/plugins/scheduler/scheduler.py
Conclusiones
Es un framework de evolución constante, actualmente en la versión 1.99, se acerca la versión 2.0 con muchos cambios en la mira.
Nos permite “prototipar” nuestras aplicaciones de forma rápida y segura, menos tiempo de programación mayor tiempo para la creación y desarrollo de nuestras ideas.
Una comunidad muy activa y participativa.
Anímate a probarlo y ayúdanos a hacerlo crecer.
Sobre el autor
Martín Mulone@mulonemartin
http://martin.tecnodoc.com.ar
https://bitbucket.org/mulonemartin/
Sobre web2py
Sitio oficial: www.web2py.com
Grupo en español: groups.google.com/group/web2py-usuarios