PyDay Rafaela 2010 Mariano Reingart reingart@gmail.

com

Historia del desarrollo Web
HTML estáticas CGI: código para generar páginas web dinámicas: Perl Python (import cgi !) Código embebido en páginas web: PHP, JSP, ASP PSP (python server pages) Frameworks web: tercera generación RoR, Struts, Symphony Django, TurboGears, Web2Py Modularidad, Reutilización, Extensibilidad, Seguridad

Ejemplo CGI
#!/usr/bin/python import MySQLdb print "Content-Type: text/html\n" # codigo repetitivo trivial print "<html><head><title>Libros</title></head><body>" print "<h1>Los ultimos 10 libros</h1><ul>" # html embebido conexion = MySQLdb.connect(user='yo', passwd='dejame_entrar', db='mi_base') # codigo duplicado en varios scripts, sin configuración cursor = conexion.cursor() cursor.execute("SELECT nombre FROM libros ORDER BY fecha_pub DESC LIMIT 10") for fila in cursor.fetchall(): print "<li> %s</li>" % fila[0] print "</ul></body></html>" conexion.close()

Ejemplo PHP
<?php include 'encabezado.php'; // Título, diseño página // Conectarse y seleccionar bd $link = mysql_connect('equipo', 'usuario', 'clave') or die('Error al conectar: ' . mysql_error()); mysql_select_db('mi_base') or die('Error!'); $query = 'SELECT * FROM my_table'; // Consultar... $result = mysql_query($query) or die(...); ?><table><?php // Imprimir resultados en HTML while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { ?><tr><?php foreach ($line as $col_value) { echo "\t\t<td>$col_value</td>\n"; } ?></tr><?php } ?></table><?php mysql_free_result($result); // Liberar resultset mysql_close($link); // cerrar conexión include 'pie.php'; // Cierre de la página ?>

Web2Py
Framework para desarrollo web Inicialmente herramienta de enseñanza Interfaz Administración completa MVC: modelo-vista-controlador Bibliotecas avanzadas: XML-RPC, RSS, etc. Sistema de tickets para errores Gluon: sesiones, request/response, cookies, seguridad, plantillas, abstracción bb.dd., caching, errors, routes, upload/download streaming, internationalización, etc.

Web2Py: comparación
Influenciado por Ruby on Rails: Focalizado en el desarrollo rápido Basado en Python (+ rápido y escalable) Más fácil administración (por web) También influenciado por Django: Generar formularios desde la base de datos Más compacto, fácil de aprender y configurar Menos verbose que los frameworks Java Más claro y simple que frameworks PHP Desarrollo y Mantenimiento más fácil

Patrón MVC:
Patron de arquitectura de software Separar Capas: Datos (Model) Presentación (View) Lógica de Control (Controller)

Web2Py: estructura
Model: Mapeador Objeto-Relacional Propio (DAL) Fácil configuración, migración (automática) Controlador Generar formularios desde la base de datos Más compacto, fácil de aprender y configurar Vista Opera sobre los datos de la vista (o el modelo) Generación del HTML (formato salida)

Web2Py: Instalación
Bajar y descomprimir Ejecutar web2py
python web2py.py o doble click web2py.exe

Web2Py: Inicio (Startup)
Bajar y ejecutar! Sin Instalación Sin Dependencias Sin Configuración Funciona en cualquier parte: Mac, Windows, Unix/Linux CPython y Jython Google App Engine

Página de bienvenida

Clickear en "Click here for the administrative interface" para ingresar a la Interfase administrativa

Interface Administrativa Web
Login (autenticación ingreso) Administrar, Crear y Diseñar Aplicaciones Probar/Depurar Integración con Mercurial

Crear una aplicación
Estructura básica: admin: interfaz administrativa examples: ejemplos welcome: bienvenida

Crear: imagenes (ejemplo)

Editar una aplicación

Editar Código
Presionar en Edit Modelo: db.py Controlador: default.py Vista: index.html index.html (htmledit)

Crear una vista, controlador, etc.
En la sección que corresponda (Views, Controller, etc.): Ir a "create file with filename" Escribir el nombre del archivo Presionar submit

Análisis de URL
http://127.0.0.1:8000/app3/default/index.html/a/b/c?name=Max

request.application == "app3" request.controller == "default" request.function == "index" request.extension == "html" request.args == ["a","b","c"] request.vars.name == "Max" Variables de entorno en request.env

Modelo (tablas)
db.define_table("category", SQLField("name")) db.define_table("image", SQLField("category_id",db.category), # referencia SQLField("title", "string"), SQLField("description", "text"), SQLField("file","upload"), # algo a subir SQLField("posted_by",db.auth_user)) # referencia db.define_table("comment", SQLField("image_id",db.image), # referencia SQLField("body","text"), SQLField("posted_by",db.auth_user), # referencia SQLField("posted_on","datetime"))

Modelo (más detalles)
# categorias únicas db.category.name.requires = IS_NOT_IN_DB(db,"category.name") # category_id será representado por nombre de categoria db.image.category_id.requires = IS_IN_DB(db,"category.id","% (name)s") db.image.title.requires = IS_NOT_EMPTY() # auto completar campos enviado_por y no mostrarlo en el formulario db.image.posted_by.default = auth.user.id if auth.user else 0 db.image.posted_by.writable = db.image.posted_by.readable=False db.comment.posted_by.default = auth.user.id if auth.user else 0 db.comment.posted_by.writable = db.comment.posted_by.readable = False # auto completar campo enviado_en y hacerlo de solo lectura db.comment.posted_on.default = request.now db.comment.posted_on.writable = False

Modelo (más detalles)
# cambiar etiqueta db.image.posted_by.label = "Posted by" # cambiar representación db.image.posted_by.represent = lambda value: \ "%(first_name)s %(last_name)s" % db.auth_user[value] # comentarios personalizados db.image.posted_by.comment = "set automatically" # cambiar automáticamente cuando se actualiza db.image.posted_by.update = auth.user.id if auth.user else 0

Controlador (default.py)
def list_images(): return dict(images=db(db.image.id>0).select()) @auth.requires_login() def post_image(): return dict(form=crud.create(db.image)) @auth.requires_login() def view_image(): image_id = request.args(0) or redirect(URL(r=request,f="index")) db.comment.image_id.default = image_id db.comment.image_id.writable = db.comment.image_id.readable = False return dict(form1=crud.read(db.image, image_id), comments=db(db.comment.image_id==image_id)\ .select(orderby=db.comment.posted_on), form2=crud.create(db.comment))

Plantillas default/list_images.html
{{extend "layout.html"}} <h1>Posted Images</h1> <ul> {{for image in images:}} <li>{{=A(image.title, _href=URL(r=request,f="view_image",args=image.id))}}</li> {{pass}} </ul> {{=A("post image",_href=URL(r=request,f="post_image"))}}

Ejemplo autenticación
Registrar (Crear) usuario en Authentication Login Register

Ingresar usuario y contraseña en Login:

Ejemplo post_image

Ejemplo list_image

Ejemplo view_image

Resumen (hasta ahora)
Procesamiento automático de formularios Vistas por defecto para todas las funciones Vista previa imágenes en crud.update/crud.read Archivos subidos menejados automágicamente Autenticación incorporada: Registración e Ingreso

Errores - tickets
Errores en el código del usuario tickets al visitante Los administradores pueden leer tickets online Se puede acceder a la documentación de web2py

Menús
models/menu.py menu = [ [‘item’,False,URL(...),[ ] ], ] False indica si el enlace es el actual [ ] es un menu opcional Vistas: {{=MENU(menu)}}

Plantillas
Embeber código: {{... código python aqui ...}} Insertar el resultado en el HTML: {{=1+3}} Usar pass para cerrar bloques si no es obvio: {{for item in "lista":}}...{{=item}}...{{pass}} {{if True:}}.v.{{else:}}.f.{{pass}} Funciones: {{def f(a):}}<a href="{{=a}}">{{=a}} </a>{{return}} Extender e incluir: {{extend "layout. html"}} {{include "otherview.html"}} Helpers: A(...,_href=....)

Más características
Herramientas del administrador (online): Modelo: sql log (historial de esquema) db select (consultas) db insert (agregar datos) DAL: abstracción bbdd Lenguajes: Traducciones a distintos idiomas T() Archivos Estáticos (sin procesamiento) Módulos adicionales ¡¡¡EJEMPLOS INCORPORADOS!!!!

Online SQL Designer

http://gaesql.appspot.com/

Layout Builder

http://www.web2py.com/layouts

de django a web2py
shell disponible pero no obligatorio url.py = ruotes.py (opcional) sin necesidad de importar web2py sin archivo de configuración ambos generan admin migraciones automáticas lenguaje de consulta más natural (SQL) vistas por defecto llenguaje de vistas: python sin limitaciones errores se registran (tickets) Helpers, Cache, soporte completo para GAE, ...
http://www.web2py.com/AlterEgo/default/show/101

Ajax (jQuery)
from gluon.contrib.markdown import WIKI def ajaxwiki(): form=FORM(TEXTAREA(_id='text'), INPUT(_type='button',_value='markdown', _onclick="ajax('ajaxwiki_onclick',['text'],'html')")) return dict(form=form,html=DIV(_id='html')) def ajaxwiki_onclick(): return WIKI(request.vars.text).xml()
http://www.web2py.com.ar/examples/simple_examples/ajaxwiki

Recomendaciones
En producción tratar de: Usar una base de datos de verdad: PostgreSQL ;-) Deshabilitar migraciones (innecesarias) Compilar la Aplicación Encapsular código en módulos (local_import) Servir usando mod_wsgi y archivos estáticos @cache y response.render Fast-downloads (revisar encabezados) Sesiones a disco (en memoria) Traducciones: T.set_current_languages('es-AR'...)

Documentación y Ayuda
Web2Py: http://www.web2py.com/ Web2Py en español: http://www.web2py.com.ar/ Documentación Web2Py: CookBook Manual (capítulos gratuitos) Wiki Python: Plantillas Módulos últiles (incluye desarrollo web) Python Argentina: http://www.python.org.ar/

Sign up to vote on this title
UsefulNot useful