2. Principales características del framework
Código libre y desarrollado por una comunidad. LGPL v3.0
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.
La seguridad como primera prioridad
No requiere instalación. Soporte PyPI
Siempre compatible con versiones anteriores
Utiliza el patrón de diseño MVC
Web forms, Validators, Uploads, Helpers, Autorizaciones, Roles, etc.
Administración de aplicaciones, errores y tickets en linea. Ayuda de creación de
aplicaciones: Wizard.
3. Web2py: Logros obtenidos
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.
“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
8. Diagrama de funcionamiento de nuestra aplicación
Agregar Cliente Agregar Producto
http://localhost:8000/default/agregar_cliente http://localhost:8000/default/agregar_producto
request request
Server
db.py
menu.py Models
controller controller
agregar_cliente agregar_producto
view layout.html view
browser browser
9. Diagrama de funcionamiento de nuestra applicación + cant. modelos
Agregar Cliente Agregar Producto
http://localhost:8000/default/agregar_cliente http://localhost:8000/default/agregar_producto
request request
Server
clientes.py
db.py Models
facturacion.py
formularios.py
menu.py
productos.py
ventas.py
settings.py
10. Problemáticas que acontecen con muchos 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.
:(
11. Orden de ejecución de los modelos
Se leen todos los archivos .py de la carpeta “models” de manera secuencial y en orden alfabético.
Models Models
clientes.py 01_settings.py
db.py 02_db.py
facturacion.py 03_menu.py
formularios.py 04_clientes.py
menu.py 05_facturacion.py
productos.py 06_productos.py
ventas.py 07_formularios.py
settings.py 08_ventas.py
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.
12. Uso de modelos condicionales
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.
models models
clientes
clientes.py
db.py 01_db.py
facturacion.py 02_menu.py
formularios.py 03_clientes.py
menu.py productos
productos.py
ventas.py 01_db.py
settings.py 02_menu.py
03_productos.py
Mejor aún
13. Uso de módulos
Models Basta con poner nuestros archivos .py en la carpeta
modules/ que contengan nuestras librerías con clases,
Controllers objetos, etc. que queremos usar en nuestras aplicaciones.
Luego hacemos uso de los mismos haciendo “import” desde
Views nuestros controladores o modelos.
Translations
Modules Modules/
__init__.py
Static Files clientes.py
facturacion.py
productos.py
14. Uso de módulos
ANTES AHORA
modules modules
__init__.py __init__.py
clientes.py clientes.py
modclientes = local_import(“clientes”) from clientes import Clientes
clientes = modclientes.Clientes() clientes = Clientes()
15. Ejemplo 1 - Uso de módulos
Modules/ Models/ Controllers/
clientes.py db.py clientes.py
db = DAL('sqlite://storage.sqlite')
from gluon import *
from clientes import Clientes
class Clientes(object):
""" Métodos de cliente """
def listar():
def __init__(self, db):
“”” Lista los Clientes “””
self.db = db
clientes = Clientes(db)
clientes.define_tables()
def define_tables(self):
lista = clientes.listar()
db = self.db
db.define_table('clientes',
return dict(lista=lista)
Field('nombre','string'),
Field('apellido','string'))
def listar(self):
db = self.db
return db(db.clientes>0).select()
16. Ejemplo 2 - Uso de módulos
Modules/ Models/ Controllers/
miapp.py db.py clientes.py
clientes.py
db = DAL('sqlite://storage.sqlite')
from gluon import *
from clientes import Clientes
class MiApp(object):
def __init__(self, db): def listar():
self.db = db “”” Lista los Clientes “””
clientes = Clientes(db)
def define_tables(self): app = MiApp(db)
db = self.db app.define_tables()
db.define_table('clientes', lista = clientes.listar()
Field('nombre','string'),
Field('apellido','string')) return dict(lista=lista)
db.define_table('productos',
Field('nombre','string'),
Field('categoria','string'))
17. Usando módulos en nuestro ambiente de desarrollo
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:
if request.is_local:
from gluon.custom_import import track_changes
track_changes()
18. Módulos: Accediendo a las variables globales: request, response, etc.
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.
from gluon import *
class MiApp(object):
def __init__(self, db):
Modules/ self.db = db
miapp.py response = current.response
request = current.request
session = current.session
19. 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.
20. Desarrollo de “plugins”
modules Controllers/
plugins clientes.py
comments.py
from gluon import *
class PluginComments(object): from clientes import Clientes
def __init__(self, db): from plugins.comments import PluginComments
self.db = db
def cliente():
def install(self):
cli = request.vars.id
db = self.db clientes = Clientes(db)
db.define_table('comments',
info = clientes.info(cli)
Field('record','integer'),
comenta =
Field('author_id', db.auth_user),
PluginComments(db).install().render(cli)
Field('comment','text'))
return self
return dict(info=info, comenta=comenta)
def render(self, record):
db = self.db
return db(db.comments.record==record).select()
21. Prácticas en el uso de controladores
EVITAR HACER
controllers controllers
default.py clientes.py
productos.py
http://localhost:8000/default/agregar_cliente http://localhost:8000/clientes/agregar
http://localhost:8000/default/agregar_producto http://localhost:8000/productos/agregar
def agregar_cliente(): def agregar():
clientes.py
return dict() return dict()
def agregar_producto(): def agregar():
return dict() productos.py
return dict()
22. 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.
El framework nos brinda ciertas herramientas que
nos permiten simplificar el desarrollo a una
manera muy sencilla, pero no única.
Un ejemplo de administración de usuarios:
usuarios = SQLFORM.grid(db.auth_user)
23. 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.
models/
db.py
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)
controllers/
default.py
@auth.requires_login()
def smartgrid():
grid=SQLFORM.smartgrid(db.person)
return dict(grid=grid)
24. 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.
25. Scheduler ejemplo
from gluon.scheduler import Scheduler
models
db.py def populate_db():
from gluon.contrib.populate import populate
tasks.py
populate(db.person,200)
populate(db.dog,200)
db.commit()
#list your task here
available_tasks = dict(populate_db=populate_db)
scheduler = Scheduler(db, available_tasks)
modules
plugins
scheduler from gluon.scheduler import Scheduler
if __name__ == "__main__":
scheduler.py """ Main execution """
scheduler.loop()
Correr scheduler como:
python web2py.py --port=8001 -S scheduler -M -R applications/scheduler/modules/plugins/scheduler/scheduler.py
Aplicación completa: http://bit.ly/qmHk1m
26. 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.
27. Sobre el autor
Martín Mulone
@mulonemartin
http://martin.tecnodoc.com.ar
https://bitbucket.org/mulonemartin/