Post on 14-Jun-2015
description
transcript
Elframeworkwebdefini1vo
AnderBeaskoetxeaabeaskoetxea@gmail.com
JaimeIrurzunjaime.irurzun@gmail.comabril2009
Índice
•Frameworksweb
•Django
•FilosoGa
•Caracterís1cas
•Rendimiento
•ConclusionesyPreguntas
Frameworksweb
Django:Filoso6a
•Bajoacoplamiento:ParadigmaMVC
•Mínimacan1daddecódigo
•Desarrolloágil
•Don’tRepeatYourself(DRY)
•Explícitofrenteaimplícito
•Consistencia
Django:Caracterís:cas
• MapeadorObjeto‐Relacional(M)
• URLsyVistas(C)
• SistemadeTemplates(V)
• Formularios
• Internacionalización
• Auten1cación[django.contrib.auth]
• Administración[django.contrib.admin]
Django:EsquemaGlobal
MapeadorO‐R
class Fabricante(models.Model):
nombre = models.CharField(blank=False, max_length=40) email = models.EmailField()
class Producto(models.Model):
descripcion = models.CharField(blank=False, max_length=100) fecha_alta = models.DateTimeField(blank=True, default=datetime.now) precio = models.DecimalField(max_digits=4, decimal_places=2) fabricante = models.ForeignKey(Fabricante)
Definiciónmodelo(DDL):
MapeadorO‐RManipulaciónmodelo(DML):
• SELECTde1registro:
p = Productos.objects.get(id=5)
• SELECTdeNregistros:
ps1 = Productos.objects.filter(precio__gt=10.95)
ps2 = Productos.objects.exclude(description__startswith=’d’)
ps3 = ps1.order_by(‘-fecha_alta’, ‘fabricante’)
MapeadorO‐RManipulaciónmodelo(DML):
• INSERT:
f = Fabricante()
f.nombre = “Apple Inc.”
f.email = “steve@apple.com”
f.save()
• UPDATE:
f = Fabricantes.objects.get(...)
f.email = “support@apple.com”
f.save()
• DELETE:
f = Fabricantes.objects.get(...)
f.delete()
Django:EsquemaInterno
• Modelo=Model • Vista=Template • Controlador=View
URLsyVistas
• Elficherourls.pyactúacomopuertadeentradaparalaspe1cionesHTTP
• SedefinenURLselegantesmedianteexpresionesregularesqueredirigenafuncionesdeviews.py
• Cadaexpresiónregulardelegaenunavista:
• Pe1ción:hfp://dominio.com/fabricante/4
• (r'^fabricante/(.*)/?$', 'dominio.app.views.ficha_fabr')
URLsyVistas
• Lafuncióndeviews.pyrecibeunobjetoespecialconlape1ciónytodoslosparámetrosdelaURL:
• Pe1ción:hfp://dominio.com/fabricante/4
• (r'^fabricante/(.*)/?$', 'dominio.app.views.ficha_fabr')
def ficha_fabr(request, fabricante_id):
f = Fabricantes.objects.get(id=fabricante_id) ps = Productos.objects.filter(fabricante=f) return render_to_response(‘fabr.html’, {‘fabricante’: f, ‘productos’: ps})
SistemadeTemplates
• Secentranexclusivamenteenlavisualización
• Sonficheros.htmlcone1quetasespecialesdeDjango:
{{ variable }}
{% if ... %} {% else %} {% if ... %}
{% else %}
{% endif %}
{% for ... in ... %}
{% empty %}
{% endfor %}
SistemadeTemplates
<html><head> <title>Ficha de fabricante</title></head><body> <h1>{{fabricante.nombre }}</h1> Productos fabricados:<br /><br /> <table> <th><td>Descripción</td><td>Precio</td></th> {% for p in productos %} <tr> <td>{{ p.descripcion }}</td> <td>{{ p.precio }}</td> </tr> {% endfor %} </table></body></html>
Ejemplobásico
SistemadeTemplatesEjemplobásico
SistemadeTemplatesHerenciadetemplates
<html><head> <title>{% block titulo %}Mi web{% endblock %}</title></head><body> <div id="menu"> {% block menu %} <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> {% endblock %} </div> <div id="contenido"> {% block contenido %}{% endblock %} </div></body></html>
SistemadeTemplatesHerenciadetemplates
{% extends "base.html" %}
{% block titulo %}Mi blog{% endblock %}
{% block contenido %}
...
{% endblock %}
SistemadeTemplatesFiltros
• Permitentrabajarsobrelosdatosrecibidos
{{ nombre|default:"<sin nombre>" }}
{{ productos|length }}
{{ comentario|striptags }}
• Posibilidaddecrearfiltrospropios
Formularios• Facilitanenormementelacreacióndeformularios
• Intervienentres1posdeclasesfundamentales:
• Widget:ComponentevisualdeHTML
• Field:RestriccionesasociadasaunWidget
• Form:ConjuntodeFieldsdeunformulario
TextInput => <input type=”text”...>CheckboxInput => <input type=”checkbox”...>
EmailFieldIPAddressField
widget, label, initial, error, ...
ContactForm (nombre, email, telefono, mensaje, ...)
Formularios
from django import forms
class ContactForm(forms.Form): asunto = forms.CharField(max_length=100) mensaje = forms.CharField() remitente = forms.EmailField()
• Paso1/3:Creacióndelaclaseformulario
Formularios
def contactar(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): # ... return HttpResponseRedirect('/gracias/') else: form = ContactForm()
return render_to_response('contactar.html', {'form': form, ...})
• Paso2/3:Programacióndelaviewasociada
Formularios
<form action="/contactar/" method="POST"> {{ form.asunto.errors }} <label for="id_asunto">Asunto:</label> {{ form.asunto }}
{{ form.mensaje.errors }} <label for="id_ mensaje">Mensaje:</label> {{ form.mensaje }}
{{ form.remitente.errors }} <label for="id_remitente">Tu email:</label> {{ form.remitente }}
<input type="submit" value="Enviar" /></form>
• Paso3/3:Inclusiónenlatemplate
Formularios
from django.db import modelsfrom django.forms import ModelForm
class Contacto(models.Model): nombre = models.CharField(max_length=100) email = models.EmailField() password = models.PasswordField() ...
class ContactoParcialForm(ModelForm): class Meta: model = Contacto fields = ('nombre', 'email')
• Alterna1va:Formulariosapar1rdelmodelo
Internacionalización
• OfreceintegraciónconlalibreríaGNUgeVextdei18n
• Unfichero.potcon1enetodoslosstringsusados
contabilidad.pot
• Encadafichero.poseguardaunatraducción
es_ES.potes_AR.poten_GB.pot
• Cada.posecompilaygeneraun.mobinario
es_ES.moes_AR.moen_GB.mo
Internacionalización
from django.utils.translation import ugettext as _
print _(“Cadena de texto”)
• ¿Cómoindicarquéstringsdebensertraducidos?
from django.utils.translation import ungettext
frase = ungettext(“Hay %(total)d resultado”, “Hay %(total)d resultados”, total) % { ‘total’: total }
• Ges1óncómodadesingularesyplurales
django.contrib.auth
Modelo
• Ofreceunsistemadeauten1caciónprefabricado
django.contrib.authVista Controlador
Templatesregistra1on_form.htmlregistra1on_complete.htmlac1vate.html
Viewslogin()logout()logout_then_login()password_change()password_change_done()password_reset()password_reset_done()redirect_to_login()password_reset_confirm()password_reset_complete()
FormulariosAdminPasswordChangeFormAuthen1ca1onFormPasswordChangeFormPasswordResetFormUserCrea1onForm
django.contrib.admin• GeneraunaaplicaciónABMsobreunmodelodedatos
1. AñadirlaaplicaciónalficheroseYngs.py
2. Añadirlaurldeaccesoalficherourls.py
INSTALLED_APPS = ( ... 'django.contrib.admin',)
from django.contrib import adminadmin.autodiscover()
urlpatterns += patterns(‘’, ... (r'^admin/(.*)', admin.site.root),)
Django:Rendimiento
Compara:va[1]
[1]Alrond’stechnoblog,2007|hfp://www.alrond.com/en/2007/jan/25/performance‐test‐of‐6‐leading‐frameworks/
Django:RendimientoVelocidad(Pe1ciones/seg)
0
275
550
825
1100CodeIgniter(PHP)Catalyst(Perl)Django(hilos)Django(hilos)+PsycoDjango(procesos)Django(procesos)+PsycoRubyOnRails1.1.6RubyOnRails1.2.1Symphony(PHP)TurboGears(Python)
Django:RendimientoMemoriaVirtualconsumida(KB)
0
75000
150000
225000
300000CodeIgniter(PHP)Catalyst(Perl)Django(hilos)Django(hilos)+PsycoDjango(procesos)Django(procesos)+PsycoRubyOnRails1.1.6RubyOnRails1.2.1Symphony(PHP)TurboGears(Python)
Django:RendimientoMemoriaRealconsumida(KB)
0
50000
100000
150000
200000CodeIgniter(PHP)Catalyst(Perl)Django(hilos)Django(hilos)+PsycoDjango(procesos)Django(procesos)+PsycoRubyOnRails1.1.6RubyOnRails1.2.1Symphony(PHP)TurboGears(Python)
Django:RendimientoConsumoCPU(%)
0
15
30
45
60CodeIgniter(PHP)Catalyst(Perl)Django(hilos)Django(hilos)+PsycoDjango(procesos)Django(procesos)+PsycoRubyOnRails1.1.6RubyOnRails1.2.1Symphony(PHP)TurboGears(Python)
Django:RendimientoTiempodeRespuesta(seg)
0
1,25
2,5
3,75
5CodeIgniter(PHP)Catalyst(Perl)Django(hilos)Django(hilos)+PsycoDjango(procesos)Django(procesos)+PsycoRubyOnRails1.1.6RubyOnRails1.2.1Symphony(PHP)TurboGears(Python)
Conclusiones
¿hacenfalta...?
:‐)
Preguntas
?