Jorge	  Bas*dame@jorgebas*da.com@jorgebas*daJaime	  Irurzunjaime@irurzun.com@jaimeirurzun
Jorge	  Bas*dame@jorgebas*da.com@jorgebas*daJaime	  Irurzun	  jaime@irurzun.com@jaimeirurzun
Evaluación
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
• Legible• Produc/vo• Portable• Extenso• Integrable• ...	  y	  Diver/doSintaxis	  intuiHva	  y	  estrictaEntre	  1/3	  y	 ...
Instalación$ sudo apt-get install pythonhttp://www.python.org/download/Mountain	  Lion	  incluye	  las	  versiones:	  2.5....
El	  Intérprete
El	  Intérprete$ python holamundo.pyhola mundo!$Modo	  Batch#!/usr/bin/env pythonprint "hola mundo!"holamundo.py
El	  Intérprete$ pythonPython 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)[GCC 4.4.3] on linux2Type "help", "copyright", "cre...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35Llong
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falsebool
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos...
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos...
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos...
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos...
Tipos	  de	  datos	  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Operadores	  h@p://docs.python.org/library/operator.html
Operadoresnuméricosa + b a - b a * b a / ba % b -a +a a ** b	  h@p://docs.python.org/library/operator.html
Operadoresnuméricosa + b a - b a * b a / ba % b -a +a a ** bcomparadoresa < b a <= b a > ba >= b a == b a != b	  h@p://doc...
Operadoresnuméricosa + b a - b a * b a / ba % b -a +a a ** bcomparadoresa < b a <= b a > ba >= b a == b a != blógicos a or...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Usos	  frecuentes:	  list
Usos	  frecuentes:	  list>>> nums = [1, 2, 3]>>> nums[0]1
Usos	  frecuentes:	  list>>> nums = [1, 2, 3]>>> nums[0]1>>> 2 in numsTrue
Usos	  frecuentes:	  list>>> nums = [1, 2, 3]>>> nums[0]1>>> nums.append(4)>>> print nums[1, 2, 3, 4]>>> 2 in numsTrue
Usos	  frecuentes:	  list>>> nums = [1, 2, 3]>>> nums[0]1>>> nums.append(4)>>> print nums[1, 2, 3, 4]>>> 2 in numsTrue>>> ...
Usos	  frecuentes:	  str
Usos	  frecuentes:	  str>>> "Python mola"[1:4]yth
Usos	  frecuentes:	  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7
Usos	  frecuentes:	  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP n...
Usos	  frecuentes:	  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP n...
Usos	  frecuentes:	  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP n...
Usos	  frecuentes:	  dict
Usos	  frecuentes:	  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]
Usos	  frecuentes:	  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]>>> us...
Usos	  frecuentes:	  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]>>> us...
Usos	  frecuentes:	  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]>>> us...
Usos	  frecuentes:	  str	  %
Usos	  frecuentes:	  str	  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio
Usos	  frecuentes:	  str	  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio>>> "%s sabe %i idiomas" % ("Hycker", 5)Hyc...
Usos	  frecuentes:	  str	  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio>>> "%s sabe %i idiomas" % ("Hycker", 5)Hyc...
juego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...enem...
juego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...enem...
MódulosEn	  la	  lista	  de	  directorios	  que	  conHene	  la	  lista	  sys.path:import math ¿Dónde	  los	  busca	  Pytho...
Módulosjuego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...
Módulosjuego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
{}Estructuras
{}Estructuras
>>> from __future__ import bracesFile "<stdin>", line 1SyntaxError: not a chanceIdentación4	  Espac/os	  para	  la	  ident...
>>> from __future__ import bracesFile "<stdin>", line 1SyntaxError: not a chanceIdentación4	  Espac/os	  para	  la	  ident...
•	  Guido	  van	  Rossum	  (2001)•	  Recomendaciones	  de	  esHlo•	  “Readability	  counts”•	  “Code	  is	  read	  much	  ...
def my_first_function(p1, p2):return "Hello World!"FuncionesMinúsculasPalabras	  separadas	  por	  _Evitar	  camelCase
def my_first_function(p1, p2):return "Hello World!"123FuncionesMinúsculasPalabras	  separadas	  por	  _Evitar	  camelCaseP...
Conversión	  de	  /pos	  h@p://docs.python.org/library/func/ons.html
Conversión	  de	  /pos>>> int(1.3)1	  h@p://docs.python.org/library/func/ons.html
Conversión	  de	  /pos>>> str(2)2>>> int(1.3)1	  h@p://docs.python.org/library/func/ons.html
Conversión	  de	  /pos>>> str(2)2>>> int(1.3)1>>> float(1)1.0	  h@p://docs.python.org/library/func/ons.html
Conversión	  de	  /pos>>> str(2)2>>> int(1.3)1>>> float(1)1.0>>> tuple([1,2,3])(1, 2, 3)	  h@p://docs.python.org/library/f...
Conversión	  de	  /pos>>> str(2)2>>> int(1.3)1>>> float(1)1.0>>> list((1,2,3))[1, 2, 3]>>> tuple([1,2,3])(1, 2, 3)	  h@p:/...
Funciones	  comunes	  h@p://docs.python.org/library/func/ons.html
Funciones	  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4	  h@p://docs.python.org/library/func/ons.html
Funciones	  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4>>> range(5)[0, 1, 2, 3, 4]>>> range(1,7)[1, 2, 3, 4, 5, 6]>...
Funciones	  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4>>> range(5)[0, 1, 2, 3, 4]>>> range(1,7)[1, 2, 3, 4, 5, 6]>...
Funciones	  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4>>> range(5)[0, 1, 2, 3, 4]>>> range(1,7)[1, 2, 3, 4, 5, 6]>...
Funciones	  interesantesSon	  sólo	  un	  ejemplo...	  h@p://docs.python.org/library/func/ons.html
Funciones	  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]Son	  sólo	  un	  ejemplo...	  h...
Funciones	  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]>>> sorted([5,1,3,4,2])[1, 2, 3,...
Funciones	  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]>>> round(1.2345, 2)1.23>>> sort...
Funciones	  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]>>> round(1.2345, 2)1.23>>> sort...
Funciones	  de	  ayuda
Funciones	  de	  ayuda>>> dir([1,2,3])[__add__, __class__, __contains__, __delattr__, __delitem__,__delslice__, __doc__, _...
Funciones	  de	  ayuda>>> dir([1,2,3])[__add__, __class__, __contains__, __delattr__, __delitem__,__delslice__, __doc__, _...
class Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % s...
class Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % s...
El	  operador	  ()• Es	  importante	  diferenciar:funcion	  	  	  vs	  	  	  funcion()Clase	  	  	  	  	  	  	  vs	  	  	 ...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
$name = "Jon";if($name == "Jon"){$name = "Jon Rocks!";}elseif($name == "Mary"){$name = "Hello Mary";}else{$name = "Who are...
$count = 0;while ($count < 5) {echo "Number ".$count;$count+=1;}count = 0while count < 5:print "Number %i" % countcount+=1...
for ($i=0; $i < 5; $i++) {echo "Number ".$count;}for i in range(4):print "Number %i" % countSentencias:	  for
try {$result = 3 / 0;} catch (Exception $e) {echo "Division by Zero"}try:result = 3 / 0except:print "Division by Zero"Sent...
Prueba	  de	  sentencias	  en	  consola
•	  Python	  es	  un	  lenguaje	  fácil	  de	  aprender.•	  Menos	  código:•	  Muchos	  Muchísimos	  menos	  errores	  de	...
•	  Python	  es	  un	  lenguaje	  fácil	  de	  aprender.•	  Menos	  código:•	  Muchos	  Muchísimos	  menos	  errores	  de	...
Ejemplo	  PythonhGp://bit.ly/ejemplo-­‐python	  	  
Ejercicio	  PythonhGp://bit.ly/ejercicio-­‐python	  	  
SolucioneshGp://bit.ly/ejercicio-­‐resueltohGp://bit.ly/ejercicio-­‐resuelto-­‐awesome
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Evolución	  de	  la	  WebDesarrollo	  Web1ª	  Generación 2ª	  Generación 3ª	  GeneraciónHTMLCGIPHPASPJSP...DjangoRailsSymf...
Frameworks	  web
Django:	  Qué	  y	  dónde
•	  Loose	  coupling,	  	  Acoplamiento	  débil.•	  Cada	  capa	  es	  independiente	  y	  desconoce	  completamente	  	  ...
•	  Loose	  coupling,	  	  Acoplamiento	  débil.•	  Cada	  capa	  es	  independiente	  y	  desconoce	  completamente	  	  ...
•	  Explicit	  is	  beier	  than	  implicit.•	  Este	  es	  un	  principio	  de	  Python.•	  Django	  no	  debe	  hacer	  ...
La	  comunidad
La	  comunidad• django-­‐users23.000	  miembros• django-­‐developers7.400	  miembros• djangoproject.com+500.000	  visitas	...
¿Quién	  usa	  Django?
¿Quién	  usa	  Django?
1.	  Instalación	  Python$ sudo apt-get install pythonhttp://www.python.org/download/Mountain	  Lion	  incluye	  las	  ver...
Configurar	  un	  motor	  de	  Base	  de	  Datos:•	  Oficiales:	  •	  PostgreSQL•	  MySQL•	  Oracle•	  SQLite•	  Comunidad:	...
Configurar	  un	  motor	  de	  Base	  de	  Datos:•	  Oficiales:	  •	  PostgreSQL•	  MySQL•	  Oracle•	  SQLite•	  Comunidad:	...
•	  Vamos	  a	  uHlizar	  SQLite	  por	  comodidad•	  Desde	  Python	  2.5	  podemos	  uHlizar	  sqlite	  	  sin	  instala...
•	  Vamos	  a	  uHlizar	  SQLite	  por	  comodidad•	  Desde	  Python	  2.5	  podemos	  uHlizar	  sqlite	  	  sin	  instala...
A:	  Paquetes	  de	  cada	  distro• apt-get install python-djangoB:	  Official	  Release• http://www.djangoproject.com/downl...
All	  Right?
All	  Right?>>> import django>>> django.VERSION(1, 4, 2, final, 0)>>> import djangoTraceback (most recent call last):File ...
Bienvenidos	  al	  mundo	  de	  Oz
*	  Incluida	  la	  carpeta	  del	  proyectoFicheros	  y	  Carpetas¿Es	  Django	  tán	  simple	  y	  fácil	  de	  usar?
*	  Incluida	  la	  carpeta	  del	  proyectoFicheros	  y	  CarpetasFicherosCarpetas¿Es	  Django	  tán	  simple	  y	  fácil...
Rails Symfony149 11735 29*	  Incluida	  la	  carpeta	  del	  proyectoFicheros	  y	  CarpetasFicherosCarpetas¿Es	  Django	 ...
Rails Symfony149 11735 29*	  Incluida	  la	  carpeta	  del	  proyectoFicheros	  y	  CarpetasFicherosCarpetas¿Es	  Django	 ...
Rails Symfony149 11735 29*	  Incluida	  la	  carpeta	  del	  proyectoFicheros	  y	  CarpetasDjango52FicherosCarpetas¿Es	  ...
Let’s	  enjoy
Crear	  nuestro	  proyectode	  5	  ficheros	  ;-­‐)
Crear	  nuestro	  proyecto$ django-admin.py startproject dwitterde	  5	  ficheros	  ;-­‐)
Crear	  nuestro	  proyecto$ django-admin.py startproject dwitter-­‐	  ¿Esto	  es	  un	  proyecto...	  ?	  	  	  Si	  os	  ...
sesngs.py
Arrancar	  nuestro	  proyectode	  5	  ficheros	  ;-­‐)
Arrancar	  nuestro	  proyectode	  5	  ficheros	  ;-­‐)$ cd dwitter$ python manage.py runserverValidating models...0 errors ...
Arrancar	  nuestro	  proyectode	  5	  ficheros	  ;-­‐)$ cd dwitter$ python manage.py runserverValidating models...0 errors ...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
MVC	  en	  DjangoModelo	  =	  Model Vista	  =	  Template Controlador	  =	  URL+View
URLs	  y	  Vistas• El	  fichero	  urls.py	  actúa	  como	  puerta	  de	  entrada	  para	  las	  pe*ciones	  HTTP• Se	  defin...
URLs	  y	  Vistas• La	  función	  de	  views.py	  recibe	  como	  parámetros	  un	  objeto	  H@pRequest	  y	  todos	  los	...
URLs	  y	  VistasEjemplo	  1:	  	  http://mysite.com/timefrom django.conf.urls.defaults import *from mysite.views import h...
URLs	  y	  Vistasfrom django.conf.urls.defaults import *from mysite.views import dentro_deurlpatterns = patterns(,url(r^ti...
URLs	  y	  Vistasfrom django.conf.urls.defaults import *from mysite.views import dentro_deurlpatterns = patterns(,url(r^ti...
¡Recuerda!:	  MVC
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Templates• Separan	  la	  lógica	  de	  presentación	  a	  una	  capa	  independiente.• Ficheros	  independientes	  (.html...
Templates• Se	  basan	  en	  dos	  *pos	  de	  objetos:	  Template()	  y	  Context().• Un	  objeto	  Template()	  con*ene	...
Templatesfrom django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimePLA...
Templates• Segunda	  aproximación	  al	  obje*vo:	  open(),	  read(),	  close()from django.http import HttpResponsefrom dj...
Templates• Segunda	  aproximación	  al	  obje*vo:	  open(),	  read(),	  close()from django.http import HttpResponsefrom dj...
Templates• Segunda	  aproximación	  al	  obje*vo:	  open(),	  read(),	  close()from django.http import HttpResponsefrom dj...
Templates• Tercera	  aproximación	  al	  obje*vo:	  get_template()from django.http import HttpResponsefrom django.template...
Templates• Tercera	  aproximación	  al	  obje*vo:	  get_template()TEMPLATE_DIRS = (/home/django/templates,)senngs.pyfrom d...
Templates• Tercera	  aproximación	  al	  obje*vo:	  get_template()TEMPLATE_DIRS = (/home/django/templates,)senngs.pyfrom d...
Templates• Obje*vo	  alcanzado:	  render()from django.shortcuts import renderfrom datetime import datetimedef hora_actual(...
Templates• Obje*vo	  alcanzado:	  render()from django.shortcuts import renderfrom datetime import datetimedef hora_actual(...
Templates• Obje*vo	  alcanzado:	  render()from django.shortcuts import renderfrom datetime import datetimedef hora_actual(...
Templates:	  TipTEMPLATE_DIRS = (/home/django/templates,)senngs.pya)
Templates:	  TipTEMPLATE_DIRS = (/home/django/templates,)senngs.py Reusable	  apps?a)
Templates:	  TipTEMPLATE_DIRS = (/home/django/templates,)senngs.py Reusable	  apps?a)b)• La	  carpeta	  /templates	  es	  ...
¡Empieza	  nuestro	  primer	  proyecto!a) Crear	  la	  app	  dwiier.website.b)Incluir	  la	  app	  en	  sesngs.py.c) Defini...
h@p://github.com/enjoydjango/dwi@er
Git
GitQuiero	  ir	  a...¿Donde	  estoy?1ª
Git$ git clone https://github.com/enjoydjango/dwitter.git$ git checkout -t origin/step-01-viewsQuiero	  ir	  a...$ git bra...
GitIgnorar	  todos	  los	  cambios	  **	  Si	  no	  habéis	  commiteado	  nada
Git$ git reset --hard HEAD$ git clean -fdIgnorar	  todos	  los	  cambios	  **	  Si	  no	  habéis	  commiteado	  nada
h@p://github.com/enjoydjango/dwi@er
Tarea:	  URLs	  y	  Vistasa) Implementar	  la	  vista	  timeline()	  para	  que	  renderice	  un	  Hmeline	  de	  twiier	 ...
Templates	  en	  detalle•	  Si,	  otro	  sistema	  de	  templates•	  Smarty,	  Tiles,	  ClearSilver	  ...	  •Describen	  c...
Filoso]a	  y	  Limitaciones•	  La	  sintaxis	  debe	  estar	  desacoplada	  del	  HTML/XML.•	  Los	  diseñadores	  saben	 ...
Templates:	  {{}}<html><head>Ejemplo templates</head><body>Hola, {{ username }}.</body></html>{username: juan}<html><head>...
Filters	  y	  Tags
Filters	  y	  Tags
Filters	  y	  Tags{{ varible|filter }}filter
Filters	  y	  Tags{{ varible|filter }}filter{% tag var1 var2 %}inline	  tag
Filters	  y	  Tags{{ varible|filter }}filter{% tag var1 var2 %}inline	  tag{% tag var1 %}...{% endtag %}block	  tag
Templates:	  tags	  {%	  %}
Templates:	  tags	  {%	  %}{% comment %} Bu! {% endcomment %}comment
Templates:	  tags	  {%	  %}{% comment %} Bu! {% endcomment %}commentfor {% for elemento in lista %}<li>{{ elemento }}<li>{...
Templates:	  tags	  {%	  %}{% comment %} Bu! {% endcomment %}commentfor {% for elemento in lista %}<li>{{ elemento }}<li>{...
Templates:	  tags	  {%	  %}
Templates:	  tags	  {%	  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor %}
Templates:	  tags	  {%	  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor ...
Templates:	  tags	  {%	  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor ...
Templates:	  tags	  {%	  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor ...
 Tarea:	  Tagsa) UHlizar	  tags	  para	  que	  el	  Hmeline	  se	  muestre	  con	  el	  siguiente	  formato:• <username>:	...
 Tarea:	  Tags	  avanzadosa) Hacer	  que	  el	  Hmeline	  muestre	  el	  mensaje	  “No	  hay	  tweets.”	  si	  el	  diccio...
Templates:	  Filters<html><head>Ejemplo templates</head><body>Hola, {{ username|title }}.</body></html>{username: juan}<ht...
Templates:	  Filters
Templates:	  Filters{username: Juan es majo}{{ username|length }}length 12
Templates:	  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo
Templates:	  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slug...
Templates:	  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slug...
Templates:	  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slug...
Templates:	  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slug...
Templates:	  Filters
Templates:	  Filters{username: Juan es <b>majo, guapo y <em>listo</em></b>}{{ username|striptags }}striptagsJuan es majo g...
Templates:	  Filters{username: Juan es <b>majo, guapo y <em>listo</em></b>}{{ username|striptags }}striptagsJuan es majo g...
Templates:	  Filters{username: Juan es <b>majo, guapo y <em>listo</em></b>}{{ username|striptags }}striptagsJuan es majo g...
Templates:	  Filters
Templates:	  Filters{url: Visitad http://www.djangoproject.com}{{ url|urlize }}urlizeVisitad <a href=”http://www.djangopro...
Templates:	  Filters{url: Visitad http://www.djangoproject.com}{{ url|urlize }}urlizeVisitad <a href=”http://www.djangopro...
Templates:	  Filters{lista: [States, [Kansas, [Lawrence, Topeka], Illinois]]}
Templates:	  Filters{lista: [States, [Kansas, [Lawrence, Topeka], Illinois]]}{{ lista|unordered_list }}unordered_list<li>S...
Templates:	  Filters
Templates:	  Filters{value: 123456789}{{ value|add:”1” }}add 123456790
Templates:	  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB
Templates:	  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB{date...
Templates:	  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB{date...
Templates:	  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB{date...
Tarea:	  Filtersa) Añadir	  a	  cada	  tweet	  del	  Hmeline	  el	  Hempo	  transcurrido:• <username>:	  <tweet><n>	  seco...
Tarea:	  Filtersb)Formatear	  las	  publicaciones	  de	  HOYGANs	  convirHendo	  el	  texto	  a	  minúsculas	  capitalizad...
Tarea:	  Filtersc) Conseguir	  que	  todas	  las	  urls	  que	  aparezcan	  en	  los	  tweets	  se	  conviertan	  en	  enl...
Herencia	  de	  Templatesbase.html <html><head><title>Mi página personal</title></head><body>{% block content %}Contenido ...
Tarea:	  Herencia	  de	  templatesa) Descargar	  nuestra	  template	  base.html.b)Incluirla	  en	  vuestra	  app.c) Hacer	...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Modelos
¿SQL?
Ejemplo	  SQLdef book_list(request):try:db = MySQLdb.connect(user=me, db=mydb,passwd=secret, host=localhost)cursor = db.cu...
Ejemplo	  SQLdef book_list(request):try:db = MySQLdb.connect(user=me, db=mydb,passwd=secret, host=localhost)cursor = db.cu...
12	  lineas	  de	  Python...	  ¬_¬
ORM	  (Object-­‐RelaHonal	  mapping)
ORM	  (Object-­‐RelaHonal	  mapping)
Ejemplo	  ORMdef book_list(request):names = Books.objects.all().order_by(name)return render(request, book_list.html, {name...
Ejemplo	  ORMdef book_list(request):names = Books.objects.all().order_by(name)return render(request, book_list.html, {name...
Fucking	  Ninjas!
Modelofrom django.db import modelsclass Books(models.Model):name = models.CharField(blank=True, max_length=100)created = m...
Modelofrom django.db import modelsclass Books(models.Model):name = models.CharField(blank=True, max_length=100)created = m...
Fucking	  Awesome	  Ninjas!
Tipos	  de	  Datos• AutoField• BigIntegerField• BooleanField• CharField• CommaSeparatedIntegerField• DateField• DateTimeFi...
Tipos	  de	  Datos• AutoField• BigIntegerField• BooleanField• CharField• CommaSeparatedIntegerField• DateField• DateTimeFi...
Propiedades	  de	  las	  Field• null (True|Flase)• blank (True|False)• choices (lista)• default (valor)• editable (True|Fa...
Propiedades	  de	  las	  Field• null (True|Flase)• blank (True|False)• choices (lista)• default (valor)• editable (True|Fa...
¿Es	  magia?	  No.BEGIN;CREATE TABLE "website_books" ("id" integer NOT NULL PRIMARY KEY,"name" varchar(100) NOT NULL,"crea...
¿Es	  magia?	  No.$ python manage.py sqlall websiteBEGIN;CREATE TABLE "website_books" ("id" integer NOT NULL PRIMARY KEY,"...
¿Es	  magia?	  No.•	  Nombres	  de	  tablas	  generados	  automáHcamente.•	  <app_name>_lower(<model_name>)•	  id	  como	 ...
Configurar	  seyngs.pyDATABASES = {default: {ENGINE: django.db.backends.,NAME: ,USER: ,PASSWORD: ,HOST: ,PORT: ,}}postgresq...
Configurar	  seyngs.pyDATABASES = {default: {ENGINE: django.db.backends.,NAME: ,USER: ,PASSWORD: ,HOST: ,PORT: ,}}123postgr...
Creando	  Tablas•	  Crea	  las	  tablas	  para	  todos	  los	  modelos	  de	  las	  apps	  instaladas	  en	  el	  fichero	 ...
Creando	  Tablas$ python manage.py syncdb•	  Crea	  las	  tablas	  para	  todos	  los	  modelos	  de	  las	  apps	  instal...
Nuestro	  primer	  modeloa)Crear	  modelo	  Tweetb)Configurar	  sesngs.pyc) Ver	  el	  SQL	  generado	  con	  sqlall
syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating tab...
syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating tab...
¿Cuantos	  sistemas	  de	  AutenHcación	  habéis	  programado?
¿Alguno	  era	  mejor	  que	  el	  anterior?	  ;-­‐)
contrib.auth	  puede	  ser	  el	  úlHmo	  :D
syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating tab...
syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating tab...
BD	  Lista	  para	  usarse
BD	  Lista	  para	  usarse
Nuestro	  primer	  modeloa)Hacer	  syncdb
Previo:	  Clases	  del	  ORMts = Publisher.objects.all()ModelManagerQuerySet
INSERT
INSERT>>> p = Publisher(... name=Apress,... address=2855 Telegraph Avenue,... city=Berkeley,... state_province=CA,... coun...
INSERT>>> p = Publisher.objects.create(... name=OReilly,... address=10 Fawcett St.,... city=Cambridge,... state_province=M...
UPDATE
UPDATE>>> ...>>> p.id52>>> p.name = Apress Publishing>>> p.save()o.save()1
UPDATE>>> Publisher.objects.all().update(country=USA)2>>> ...>>> p.id52>>> p.name = Apress Publishing>>> p.save()o.save()q...
DELETE
DELETE>>> ...>>> p.id52>>> p.delete()o.delete()1
DELETE>>> ps = Publisher.objects.all()>>> ps.delete()>>> ...>>> p.id52>>> p.delete()o.delete()queryset.delete()1n
SELECT	  de	  1	  resultado
SELECT	  de	  1	  resultado>>> Publisher.objects.get(name="Apress")<Publisher: Apress>.get(...)
SELECT	  de	  1	  resultado>>> Publisher.objects.get(name="Apress")<Publisher: Apress>.get(...)>>> Publisher.objects.get(n...
SELECT	  de	  1	  resultado>>> Publisher.objects.get(name="Apress")<Publisher: Apress>.get(...)>>> Publisher.objects.get(c...
SELECT	  de	  N	  resultados
SELECT	  de	  N	  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()
SELECT	  de	  N	  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()>>> Publisher.obje...
SELECT	  de	  N	  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()>>> Publisher.obje...
SELECT	  de	  N	  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()>>> Publisher.obje...
get(),	  filter()	  y	  exclude()
get(),	  filter()	  y	  exclude()Modelo.objects.filter(campo1="valor1", campo2="valor2")Los	  parámetros	  pueden	  indicar...
get(),	  filter()	  y	  exclude()Modelo.objects.filter(campo1="valor1", campo2="valor2")Los	  parámetros	  pueden	  indicar...
ORDER	  BY
ORDER	  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)
ORDER	  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)>>> Publisher.obj...
ORDER	  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)>>> Publisher.obj...
ORDER	  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)>>> Publisher.obj...
Slicing
Slicing>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>[n:m]>>> Publisher.objects.order_by("name")[:2][<Publis...
Slicing>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>[n:m]>>> Publisher.objects.order_by("name")[:2][<Publis...
Slicing>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>[n:m]>>> Publisher.objects.order_by("name")[:2][<Publis...
Related	  Objects
Related	  ObjectsOneToOneFieldclass Coche(models.Model):motor = OneToOneField(Motor)class Motor(models.Model):...11
Related	  ObjectsOneToOneFieldclass Coche(models.Model):motor = OneToOneField(Motor)class Motor(models.Model):...>>> c.mot...
Related	  ObjectsOneToOneFieldclass Coche(models.Model):motor = OneToOneField(Motor)class Motor(models.Model):...>>> c.mot...
Related	  Objects
Related	  ObjectsForeignKeyFieldclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog)1n
Related	  ObjectsForeignKeyFieldclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog)>>> p.blo...
Related	  Objects
Related	  ObjectsManyToManyFieldclass Post(models.Model):tags = ManyToManyField(Tag)class Tag(models.Model):...nm
Related	  ObjectsManyToManyFieldclass Post(models.Model):tags = ManyToManyField(Tag)class Tag(models.Model):...>>> p.tags....
Related	  Objects
Related	  ObjectsEn	  todas	  ellas	  podemos	  renombrar	  el	  puntero	  inversoclass Blog(models.Model):...class Post(m...
Related	  ObjectsEn	  todas	  ellas	  podemos	  renombrar	  el	  puntero	  inversoclass Blog(models.Model):...class Post(m...
Related	  ObjectsEn	  todas	  ellas	  podemos	  renombrar	  el	  puntero	  inversoclass Blog(models.Model):...class Post(m...
Y	  la	  guinda	  final:	  ¡Todo	  es	  LAZY!
Laziness
Laziness• Las	  consultas	  sólo	  se	  ejecutarán	  cuando	  realmente	  se	  necesite	  obtener	  los	  objetos.	  En	  ...
Nota:	  __unicode__()
Nota:	  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
Nota:	  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
Nota:	  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
Nota:	  __unicode__()class Publisher(models.Model):...def __unicode__(self):return self.name>>> Publisher.objects.all()[<P...
Nota:	  __unicode__()class Publisher(models.Model):...def __unicode__(self):return self.name>>> Publisher.objects.all()[<P...
Usando	  el	  ORMa)Insertar	  varios	  Tweets	  desde	  la	  shell.b)Modificar	  views.timeline	  para	  que	  uHlice	  los...
Usando	  el	  ORMc) Implementar	  la	  vista	  tweet_page()	  como	  permalink	  de	  un	  tweet:‣ URL:	  	  tweet/<tweet_...
Profiles
Profile•	  Problema:	  El	  modelo	  User	  de	  django.contrib.auth	  no	  puede	  contener	  toda	  la	  información	  qu...
Profilemodels.py
Profileclass Profile(models.Model):user = models.OneToOneField(User, unique=True)bio = models.CharField(blank=True, max_len...
Profile•Donde	  tengamos	  el	  User	  tendremos	  el	  Profile.•Donde	  tengamos	  el	  Profile,	  tendremos	  el	  User.
Profile>>> from django.contrib.auth.models import User>>> u = User.objects.get(id=1)>>> type(u)<class django.contrib.auth.m...
1	  User	  =	  1	  Profile	  ¿Cuándo	  se	  crea	  un	  User?
Signals•	  Django	  incorpora	  un	  dispacher	  de	  señales	  para	  ayudar	  a	  crear	  aplicaciones	  reuHlizables.•	...
Signals
Signalsdef create_user_profile(sender, instance, created, **kwargs):if created:Profile.objects.create(user=instance)from d...
Users	  en	  dwiiera)Crear	  el	  modelo	  Profileb)Crear	  signal	  para	  agregar	  un	  objeto	  Profile	  a	  cada	  o...
Followers
Profilemodels.py
Profileclass Profile(models.Model):user = models.OneToOneField(User, unique=True)bio = models.CharField(blank=True, max_len...
Users	  en	  dwiiera)Añadir	  ManyToMany	  para	  los	  followers.b)Eliminar	  BD.c) Hacer	  syncdb
1,2,3	  Borrar	  la	  BD....	  1,2,3...	  Borrar	  la	  BD
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
CRUD:	  Create,	  Retrieve,	  Update	  &	  Delete
django.contrib.admin123
django.contrib.admin123
django.contrib.admin1
Django	  admin:	  Instalaciónfrom django.conf.urls.defaults import *# Uncomment the next two lines to enable the admin:# f...
Django	  admin:	  Instalaciónfrom django.conf.urls.defaults import *# Uncomment the next two lines to enable the admin:fro...
Django	  admin:	  InstalaciónINSTALLED_APPS = (django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,dja...
Django	  admin:	  InstalaciónINSTALLED_APPS = (django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,dja...
Actualizando	  la	  BD
Actualizando	  la	  BD$ python manage.py syncdbCreating table django_admin_logInstalling index for admin.LogEntry modelAdm...
¿Y	  nuestra	  app??
¿Y	  nuestra	  app?
admin.py• Cada	  app	  debe	  de	  tener	  el	  suyo.• Define	  qué	  modelos	  serán	  visibles	  desde	  el	  admin	  y	 ...
Instalar	  Admina)Configurar	  urls.pyb)Configurar	  sesngs.pyc) Hacer	  syncdb
Instalar	  Admind)Comprobar	  que	  no	  están	  Tweet	  y	  Profilee)Añadir	  admin.pyf) Probar	  Administración.
Fixtures
Fixtures•	  Es	  muy	  aburrido	  crear	  juegos	  de	  datos	  cada	  vez	  que	  se	  elimina	  una	  tabla	  /	  BD.•	 ...
Fixtures•	  Es	  muy	  aburrido	  crear	  juegos	  de	  datos	  cada	  vez	  que	  se	  elimina	  una	  tabla	  /	  BD.•	 ...
Fixtures•	  Es	  muy	  aburrido	  crear	  juegos	  de	  datos	  cada	  vez	  que	  se	  elimina	  una	  tabla	  /	  BD.•	 ...
Tarea:	  Avance	  en	  dwiiera)Implementar	  la	  vista	  user_page()	  para	  ofrecer	  un	  perfil	  de	  usuario	  con	 ...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Formularios
Clases	  involucradas
Clases	  involucradasWidget Componente	  visual	  equivalente	  a	  HTMLTextInputCheckboxInput<input type=text...><input t...
Clases	  involucradasWidget Componente	  visual	  equivalente	  a	  HTMLTextInputCheckboxInput<input type=text...><input t...
Clases	  involucradasWidget Componente	  visual	  equivalente	  a	  HTMLTextInputCheckboxInput<input type=text...><input t...
Fields
Fields■ BooleanField■ CharField■ ChoiceField■ TypedChoiceField■ DateField■ DateTimeField■ DecimalField■ EmailField■ FileFi...
Fields■ BooleanField■ CharField■ ChoiceField■ TypedChoiceField■ DateField■ DateTimeField■ DecimalField■ EmailField■ FileFi...
Creación	  de	  un	  Formfrom django import formsclass ContactForm(forms.Form):subject = forms.CharField(max_length=100, l...
Creación	  de	  un	  Form<html><body><h1>Contact us</h1>{% if form.errors %}<p style="color: red;">Please correct the erro...
Creación	  de	  un	  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(reques...
Creación	  de	  un	  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(reques...
Creación	  de	  un	  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(reques...
Creación	  de	  un	  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(reques...
Validación	  propiafrom django import formsclass ContactForm(forms.Form):subject = forms.CharField(max_length=100)email = ...
Validación	  propiafrom django import formsclass ContactForm(forms.Form):subject = forms.CharField(max_length=100)email = ...
Maquetación	  propia...<form action="" method="post"><div class="field">{{ form.subject.errors }}<label for="id_subject">S...
Forms	  a	  parHr	  de	  Models:	  El	  COLMO	  del	  DRY
Forms	  a	  par/r	  de	  Modelsfrom django.db import modelsclass Author(models.Model):name = models.CharField(max_length=1...
Primer	  Form	  en	  dwiiera)Crear	  un	  Form	  que	  permita	  publicar	  tweets	  desde	  Hmeline.html	  al	  usuario	 ...
Tarea:	  Avance	  en	  dwiiera)Implementar	  la	  vista	  users_list()	  para	  visualizar	  la	  lista	  de	  usuarios:‣ ...
Índice1.Pythona. Introducciónb.Tipos	  de	  datosc. Operadoresd.Usos	  frecuentese. Estructurasf. Sentenciasg. Ejercicio2....
Magia	  avanzada
Magia	  avanzada1. Views	  avanzadas2. Context	  Processors3. Custom	  Template	  Filters	  &	  Tags4. Middleware5. Intern...
Magia	  avanzada1. Views	  avanzadas2. Context	  Processors3. Custom	  Template	  Filters	  &	  Tags4. Middleware5. Intern...
Views	  avanzadasfrom django.conf.urls.defaults import *urlpatterns = patterns(,url(r^hello/$, mysite.views.hello),url(r^t...
Views	  avanzadasfrom django.conf.urls.defaults import *urlpatterns = patterns(,url(r^hello/$, mysite.views.hello),url(r^t...
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Desarrollo web ágil con Python y Django
Upcoming SlideShare
Loading in...5
×

Desarrollo web ágil con Python y Django

9,933

Published on

Curso de Python y Django impartido con Jorge Bastida para Bizkaia Enpresa Digitala en el European Software Institute de Zamudio, enero 2011.

Published in: Technology
2 Comments
18 Likes
Statistics
Notes
No Downloads
Views
Total Views
9,933
On Slideshare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
647
Comments
2
Likes
18
Embeds 0
No embeds

No notes for slide

Desarrollo web ágil con Python y Django

  1. 1. Jorge  Bas*dame@jorgebas*da.com@jorgebas*daJaime  Irurzunjaime@irurzun.com@jaimeirurzun
  2. 2. Jorge  Bas*dame@jorgebas*da.com@jorgebas*daJaime  Irurzun  jaime@irurzun.com@jaimeirurzun
  3. 3. Evaluación
  4. 4. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  5. 5. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  6. 6. • Legible• Produc/vo• Portable• Extenso• Integrable• ...  y  Diver/doSintaxis  intuiHva  y  estrictaEntre  1/3  y  1/5  más  conciso  que  Java  o  C++GNU/Linux,  Windows,  Mac  OS  X,  ...Standard  Library,  Third  parHesC,  C++,  Java,  .NET,  COM,  WS,  CORBA,  ...
  7. 7. Instalación$ sudo apt-get install pythonhttp://www.python.org/download/Mountain  Lion  incluye  las  versiones:  2.5.6,    2.6.7, 2.7.2
  8. 8. El  Intérprete
  9. 9. El  Intérprete$ python holamundo.pyhola mundo!$Modo  Batch#!/usr/bin/env pythonprint "hola mundo!"holamundo.py
  10. 10. El  Intérprete$ pythonPython 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)[GCC 4.4.3] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> print "hola mundo!"hola mundo!Modo  Interac*vo$ python holamundo.pyhola mundo!$Modo  Batch#!/usr/bin/env pythonprint "hola mundo!"holamundo.py
  11. 11. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  12. 12. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject
  13. 13. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35Llong
  14. 14. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falsebool
  15. 15. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos" """n lines"""str
  16. 16. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos" """n lines"""str[1, [2, three], 4]list
  17. 17. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos" """n lines"""str[1, [2, three], 4]list{food: spam, taste: yum}dict
  18. 18. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos" """n lines"""str[1, [2, three], 4]list{food: spam, taste: yum}dict(1, spam, 4, U)tuple
  19. 19. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.htmlobject1234 3.1415int float35LlongTrue Falseboolspam "guidos" """n lines"""str[1, [2, three], 4]list{food: spam, taste: yum}dict(1, spam, 4, U)tuple¡Tipado  dinámico!
  20. 20. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  21. 21. Operadores  h@p://docs.python.org/library/operator.html
  22. 22. Operadoresnuméricosa + b a - b a * b a / ba % b -a +a a ** b  h@p://docs.python.org/library/operator.html
  23. 23. Operadoresnuméricosa + b a - b a * b a / ba % b -a +a a ** bcomparadoresa < b a <= b a > ba >= b a == b a != b  h@p://docs.python.org/library/operator.html
  24. 24. Operadoresnuméricosa + b a - b a * b a / ba % b -a +a a ** bcomparadoresa < b a <= b a > ba >= b a == b a != blógicos a or b a and b not a  h@p://docs.python.org/library/operator.html
  25. 25. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  26. 26. Usos  frecuentes:  list
  27. 27. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1
  28. 28. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1>>> 2 in numsTrue
  29. 29. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1>>> nums.append(4)>>> print nums[1, 2, 3, 4]>>> 2 in numsTrue
  30. 30. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1>>> nums.append(4)>>> print nums[1, 2, 3, 4]>>> 2 in numsTrue>>> len(nums)4
  31. 31. Usos  frecuentes:  str
  32. 32. Usos  frecuentes:  str>>> "Python mola"[1:4]yth
  33. 33. Usos  frecuentes:  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7
  34. 34. Usos  frecuentes:  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP no")PHP no mola
  35. 35. Usos  frecuentes:  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP no")PHP no mola>>> "Python mola".split(" ")[Python, mola]
  36. 36. Usos  frecuentes:  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP no")PHP no mola>>> "Python mola".split(" ")[Python, mola]>>> " ".join(["Python", "mola"])"Python mola"
  37. 37. Usos  frecuentes:  dict
  38. 38. Usos  frecuentes:  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]
  39. 39. Usos  frecuentes:  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]>>> user[nick]neo>>> user.get(age, 26)26
  40. 40. Usos  frecuentes:  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]>>> user[nick]neo>>> user.get(age, 26)26>>> nick in userTrue
  41. 41. Usos  frecuentes:  dict>>> user = {nick: neo, phone: 5555}>>> user.keys()[nick, phone]>>> user.values()[neo, 5555]>>> user[nick]neo>>> user.get(age, 26)26>>> nick in userTrue>>> user.update({nick: alatar, age: 25})>>> user{nick: alatar, phone: 5555, age: 25}
  42. 42. Usos  frecuentes:  str  %
  43. 43. Usos  frecuentes:  str  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio
  44. 44. Usos  frecuentes:  str  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio>>> "%s sabe %i idiomas" % ("Hycker", 5)Hycker sabe 5 idiomas
  45. 45. Usos  frecuentes:  str  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio>>> "%s sabe %i idiomas" % ("Hycker", 5)Hycker sabe 5 idiomas>>> t = "%(NOMBRE)s sabe %(IDIOMAS)i idiomas">>> v = {NOMBRE: Hycker, IDIOMAS: 5}>>> t % vHycker sabe 5 idiomas
  46. 46. juego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...enemigos/__init__.pyseta.pytortuga.pybomba.py...Módulos1. Un  módulo  es  un  fichero  .py2. Los  módulos  pueden  organizarse  en  paquetes.3. Un  paquete  es  una  carpeta  que  conHene  un  fichero  con  nombre  __init__.py
  47. 47. juego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...enemigos/__init__.pyseta.pytortuga.pybomba.py...Módulos1. Un  módulo  es  un  fichero  .py2. Los  módulos  pueden  organizarse  en  paquetes.3. Un  paquete  es  una  carpeta  que  conHene  un  fichero  con  nombre  __init__.py123
  48. 48. MódulosEn  la  lista  de  directorios  que  conHene  la  lista  sys.path:import math ¿Dónde  los  busca  Python?1. El  directorio  actual:2. El  directorio  site-packages  de  nuestro  Python:3. Los  directorios  apuntados  por  PYTHONPATH:4. El  directorio  de  la  instalación  de  Python:.//usr/local/lib/python2.6/site-packages/usr/lib/python2.6/$ env | grep PYTHONPATH
  49. 49. Módulosjuego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...enemigos/__init__.pyseta.pytortuga.pybomba.py...
  50. 50. Módulosjuego/__init__.pybonus/__init__.pyestrella.pymoneda.pyplanta.py...personajes/__init__.pymario.pyluigi.pyprincesa.py...enemigos/__init__.pyseta.pytortuga.pybomba.py...>>> from juego.personajes.mario import Mario>>> Mario()>>> from juego.personajes.mario import *>>> Mario()>>> from juego import personajes>>> personajes.mario.Mario()
  51. 51. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  52. 52. {}Estructuras
  53. 53. {}Estructuras
  54. 54. >>> from __future__ import bracesFile "<stdin>", line 1SyntaxError: not a chanceIdentación4  Espac/os  para  la  identación
  55. 55. >>> from __future__ import bracesFile "<stdin>", line 1SyntaxError: not a chanceIdentación4  Espac/os  para  la  identaciónPEP 8
  56. 56. •  Guido  van  Rossum  (2001)•  Recomendaciones  de  esHlo•  “Readability  counts”•  “Code  is  read  much  more  ohen  than  it  is  wriien.”•  Muy  recomendable  importante  seguirlo.PEP 8¿PEP  8?  h@p://www.python.org/dev/peps/pep-­‐0008/
  57. 57. def my_first_function(p1, p2):return "Hello World!"FuncionesMinúsculasPalabras  separadas  por  _Evitar  camelCase
  58. 58. def my_first_function(p1, p2):return "Hello World!"123FuncionesMinúsculasPalabras  separadas  por  _Evitar  camelCasePEP 8
  59. 59. Conversión  de  /pos  h@p://docs.python.org/library/func/ons.html
  60. 60. Conversión  de  /pos>>> int(1.3)1  h@p://docs.python.org/library/func/ons.html
  61. 61. Conversión  de  /pos>>> str(2)2>>> int(1.3)1  h@p://docs.python.org/library/func/ons.html
  62. 62. Conversión  de  /pos>>> str(2)2>>> int(1.3)1>>> float(1)1.0  h@p://docs.python.org/library/func/ons.html
  63. 63. Conversión  de  /pos>>> str(2)2>>> int(1.3)1>>> float(1)1.0>>> tuple([1,2,3])(1, 2, 3)  h@p://docs.python.org/library/func/ons.html
  64. 64. Conversión  de  /pos>>> str(2)2>>> int(1.3)1>>> float(1)1.0>>> list((1,2,3))[1, 2, 3]>>> tuple([1,2,3])(1, 2, 3)  h@p://docs.python.org/library/func/ons.html
  65. 65. Funciones  comunes  h@p://docs.python.org/library/func/ons.html
  66. 66. Funciones  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4  h@p://docs.python.org/library/func/ons.html
  67. 67. Funciones  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4>>> range(5)[0, 1, 2, 3, 4]>>> range(1,7)[1, 2, 3, 4, 5, 6]>>> range(1,7,2)[1, 3, 5]  h@p://docs.python.org/library/func/ons.html
  68. 68. Funciones  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4>>> range(5)[0, 1, 2, 3, 4]>>> range(1,7)[1, 2, 3, 4, 5, 6]>>> range(1,7,2)[1, 3, 5]>>> type(True)<type bool>>>> type("Python Mola")<type str>  h@p://docs.python.org/library/func/ons.html
  69. 69. Funciones  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4>>> range(5)[0, 1, 2, 3, 4]>>> range(1,7)[1, 2, 3, 4, 5, 6]>>> range(1,7,2)[1, 3, 5]>>> sum([0,1,2,3,4])10>>> sum(range(5))10>>> type(True)<type bool>>>> type("Python Mola")<type str>Y  un  muy  largo  etc...  h@p://docs.python.org/library/func/ons.html
  70. 70. Funciones  interesantesSon  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html
  71. 71. Funciones  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]Son  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html
  72. 72. Funciones  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]>>> sorted([5,1,3,4,2])[1, 2, 3, 4, 5]Son  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html
  73. 73. Funciones  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]>>> round(1.2345, 2)1.23>>> sorted([5,1,3,4,2])[1, 2, 3, 4, 5]Son  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html
  74. 74. Funciones  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> zip(a,b)[(1, 4), (2, 5), (3, 6)]>>> round(1.2345, 2)1.23>>> sorted([5,1,3,4,2])[1, 2, 3, 4, 5]>>> map(str,[1,2,3,4,5])[1, 2, 3, 4, 5]Son  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html
  75. 75. Funciones  de  ayuda
  76. 76. Funciones  de  ayuda>>> dir([1,2,3])[__add__, __class__, __contains__, __delattr__, __delitem__,__delslice__, __doc__, __eq__, __format__, __ge__,__getattribute__, __getitem__, __getslice__, __gt__, __hash__,__iadd__, __imul__, __init__, __iter__, __le__, __len__,__lt__, __mul__, __ne__, __new__, __reduce__, __reduce_ex__,__repr__, __reversed__, __rmul__, __setattr__, __setitem__,__setslice__, __sizeof__, __str__, __subclasshook__, append,count, extend, index, insert, pop, remove, reverse, sort]
  77. 77. Funciones  de  ayuda>>> dir([1,2,3])[__add__, __class__, __contains__, __delattr__, __delitem__,__delslice__, __doc__, __eq__, __format__, __ge__,__getattribute__, __getitem__, __getslice__, __gt__, __hash__,__iadd__, __imul__, __init__, __iter__, __le__, __len__,__lt__, __mul__, __ne__, __new__, __reduce__, __reduce_ex__,__repr__, __reversed__, __rmul__, __setattr__, __setitem__,__setslice__, __sizeof__, __str__, __subclasshook__, append,count, extend, index, insert, pop, remove, reverse, sort]>>> help(filter)Help on built-in function filter in module __builtin__:filter(...)filter(function or None, sequence) -> list, tuple, or stringReturn those items of sequence for which function(item) is true. Iffunction is None, return the items that are true. If sequence is a tupleor string, return the same type, else return a list.(END)
  78. 78. class Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % self.nameClasess = Student("Jorge", 24)camelCase
  79. 79. class Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % self.name1 2345Clasess = Student("Jorge", 24)camelCasePEP 8
  80. 80. El  operador  ()• Es  importante  diferenciar:funcion      vs      funcion()Clase              vs        Clase()• El  operador  ()  permite:• Invocar  funciones:• Instanciar  clases:resultado = funcion()objeto = Clase("param1")
  81. 81. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  82. 82. $name = "Jon";if($name == "Jon"){$name = "Jon Rocks!";}elseif($name == "Mary"){$name = "Hello Mary";}else{$name = "Who are you?"}name = "Jon"if name == "Jon":name = "Jon Rocks!"elif name == "Mary":name = "Hello Mary"else:name = "Who are you?"Sentencias:  if-­‐else
  83. 83. $count = 0;while ($count < 5) {echo "Number ".$count;$count+=1;}count = 0while count < 5:print "Number %i" % countcount+=1Sentencias:  while
  84. 84. for ($i=0; $i < 5; $i++) {echo "Number ".$count;}for i in range(4):print "Number %i" % countSentencias:  for
  85. 85. try {$result = 3 / 0;} catch (Exception $e) {echo "Division by Zero"}try:result = 3 / 0except:print "Division by Zero"Sentencias:  try-­‐except
  86. 86. Prueba  de  sentencias  en  consola
  87. 87. •  Python  es  un  lenguaje  fácil  de  aprender.•  Menos  código:•  Muchos  Muchísimos  menos  errores  de  Sintaxis.•  Mayor  velocidad  de  escritura.•  ProtoHpado...  UHlizado  por  grandes  empresas.Conclusiones
  88. 88. •  Python  es  un  lenguaje  fácil  de  aprender.•  Menos  código:•  Muchos  Muchísimos  menos  errores  de  Sintaxis.•  Mayor  velocidad  de  escritura.•  ProtoHpado...  UHlizado  por  grandes  empresas.etc...Conclusiones
  89. 89. Ejemplo  PythonhGp://bit.ly/ejemplo-­‐python    
  90. 90. Ejercicio  PythonhGp://bit.ly/ejercicio-­‐python    
  91. 91. SolucioneshGp://bit.ly/ejercicio-­‐resueltohGp://bit.ly/ejercicio-­‐resuelto-­‐awesome
  92. 92. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  93. 93. Evolución  de  la  WebDesarrollo  Web1ª  Generación 2ª  Generación 3ª  GeneraciónHTMLCGIPHPASPJSP...DjangoRailsSymfony...
  94. 94. Frameworks  web
  95. 95. Django:  Qué  y  dónde
  96. 96. •  Loose  coupling,    Acoplamiento  débil.•  Cada  capa  es  independiente  y  desconoce  completamente    a  las  demás.•  Menos  código.•  Rápido  desarrollo.•  Esto  es  el  siglo  21,  todo  el  trabajo  tedioso  hay  que  evitarlo.•  Don’t  Repeat  Yourself  (DRY)Filoso]a
  97. 97. •  Loose  coupling,    Acoplamiento  débil.•  Cada  capa  es  independiente  y  desconoce  completamente    a  las  demás.•  Menos  código.•  Rápido  desarrollo.•  Esto  es  el  siglo  21,  todo  el  trabajo  tedioso  hay  que  evitarlo.•  Don’t  Repeat  Yourself  (DRY)Every distinct concept and/or piece of data should live inone, and only one, place. Redundancy is bad.Normalization is good.”“Filoso]a
  98. 98. •  Explicit  is  beier  than  implicit.•  Este  es  un  principio  de  Python.•  Django  no  debe  hacer  demasiada  “Magia”.•  Si  algo  es  “Mágico”  ha  de  haber  una  buena  razón.•  Consistencia•  Ha  de  ser  consistente  a  todos  los  niveles.•  Eficiencia,  Seguridad,  Flexibilidad  y  Simplicidad.Filoso]a  h@p://docs.djangoproject.com/en/dev/misc/design-­‐philosophies/
  99. 99. La  comunidad
  100. 100. La  comunidad• django-­‐users23.000  miembros• django-­‐developers7.400  miembros• djangoproject.com+500.000  visitas  únicas  mensuales
  101. 101. ¿Quién  usa  Django?
  102. 102. ¿Quién  usa  Django?
  103. 103. 1.  Instalación  Python$ sudo apt-get install pythonhttp://www.python.org/download/Mountain  Lion  incluye  las  versiones:  2.5.6,  2.6.7, 2.7.2
  104. 104. Configurar  un  motor  de  Base  de  Datos:•  Oficiales:  •  PostgreSQL•  MySQL•  Oracle•  SQLite•  Comunidad:  •  Sybase  SQL  Anywhere•  IBM  DB2•  Microsoh  SQL  Server  2005•  Firebird•  ODBC2.  Instalación  SGBD
  105. 105. Configurar  un  motor  de  Base  de  Datos:•  Oficiales:  •  PostgreSQL•  MySQL•  Oracle•  SQLite•  Comunidad:  •  Sybase  SQL  Anywhere•  IBM  DB2•  Microsoh  SQL  Server  2005•  Firebird•  ODBC2.  Instalación  SGBD
  106. 106. •  Vamos  a  uHlizar  SQLite  por  comodidad•  Desde  Python  2.5  podemos  uHlizar  sqlite    sin  instalar  nada.2.  Instalación  SGBD
  107. 107. •  Vamos  a  uHlizar  SQLite  por  comodidad•  Desde  Python  2.5  podemos  uHlizar  sqlite    sin  instalar  nada.2.  Instalación  SGBD
  108. 108. A:  Paquetes  de  cada  distro• apt-get install python-djangoB:  Official  Release• http://www.djangoproject.com/download/• python setup.py installC:  Github• git clone https://github.com/django/django.git3.  Instalación  Django
  109. 109. All  Right?
  110. 110. All  Right?>>> import django>>> django.VERSION(1, 4, 2, final, 0)>>> import djangoTraceback (most recent call last):File "<stdin>", line 1, in <module>ImportError: No module named django
  111. 111. Bienvenidos  al  mundo  de  Oz
  112. 112. *  Incluida  la  carpeta  del  proyectoFicheros  y  Carpetas¿Es  Django  tán  simple  y  fácil  de  usar?
  113. 113. *  Incluida  la  carpeta  del  proyectoFicheros  y  CarpetasFicherosCarpetas¿Es  Django  tán  simple  y  fácil  de  usar?
  114. 114. Rails Symfony149 11735 29*  Incluida  la  carpeta  del  proyectoFicheros  y  CarpetasFicherosCarpetas¿Es  Django  tán  simple  y  fácil  de  usar?
  115. 115. Rails Symfony149 11735 29*  Incluida  la  carpeta  del  proyectoFicheros  y  CarpetasFicherosCarpetas¿Es  Django  tán  simple  y  fácil  de  usar?
  116. 116. Rails Symfony149 11735 29*  Incluida  la  carpeta  del  proyectoFicheros  y  CarpetasDjango52FicherosCarpetas¿Es  Django  tán  simple  y  fácil  de  usar?
  117. 117. Let’s  enjoy
  118. 118. Crear  nuestro  proyectode  5  ficheros  ;-­‐)
  119. 119. Crear  nuestro  proyecto$ django-admin.py startproject dwitterde  5  ficheros  ;-­‐)
  120. 120. Crear  nuestro  proyecto$ django-admin.py startproject dwitter-­‐  ¿Esto  es  un  proyecto...  ?      Si  os  ve  mi  jefe....!"" dwitter#   !"" __init__.py#   !"" settings.py#   !"" urls.py#   $"" wsgi.py$"" manage.py-­‐  Sí,  disponemos  de  un  proyecto  ‘funcional’  en  django.de  5  ficheros  ;-­‐)
  121. 121. sesngs.py
  122. 122. Arrancar  nuestro  proyectode  5  ficheros  ;-­‐)
  123. 123. Arrancar  nuestro  proyectode  5  ficheros  ;-­‐)$ cd dwitter$ python manage.py runserverValidating models...0 errors foundDjango version 1.4, using settings dwitter.settingsDevelopment server is running at http://127.0.0.1:8000/Quit the server with CONTROL-C.
  124. 124. Arrancar  nuestro  proyectode  5  ficheros  ;-­‐)$ cd dwitter$ python manage.py runserverValidating models...0 errors foundDjango version 1.4, using settings dwitter.settingsDevelopment server is running at http://127.0.0.1:8000/Quit the server with CONTROL-C.
  125. 125. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  126. 126. MVC  en  DjangoModelo  =  Model Vista  =  Template Controlador  =  URL+View
  127. 127. URLs  y  Vistas• El  fichero  urls.py  actúa  como  puerta  de  entrada  para  las  pe*ciones  HTTP• Se  definen  URLs  elegantes  mediante  expresiones  regulares  que  redirigen  a  funciones  de  views.pyurls.pyviews.pyhGp://mysite.com/about/html ...¿urlpaGerns?
  128. 128. URLs  y  Vistas• La  función  de  views.py  recibe  como  parámetros  un  objeto  H@pRequest  y  todos  los  parámetros  de  la  URL  capturados,  teniendo  que  devolver  siempre  un  objeto  H@pResponseviews.pyH@pRequest(),  ...H@pResponse()
  129. 129. URLs  y  VistasEjemplo  1:    http://mysite.com/timefrom django.conf.urls.defaults import *from mysite.views import hora_actualurlpatterns = patterns(,url(r^time/$, hora_actual),)from django.http import HttpResponsefrom datetime import datetimedef hora_actual(request):now = datetime.now()html = "Son las %s." % nowreturn HttpResponse(html)urls.pyviews.py
  130. 130. URLs  y  Vistasfrom django.conf.urls.defaults import *from mysite.views import dentro_deurlpatterns = patterns(,url(r^time/plus/(d{1,2})/$, dentro_de),)from django.http import HttpResponsefrom datetime import datetime, timedeltadef dentro_de(request, offset):offset = int(offset)dt = datetime.now() + timedelta(hours=offset)html = "En %i hora(s), serán las %s." % (offset, dt)return HttpResponse(html)urls.pyviews.pyEjemplo  2:    http://mysite.com/time/plus/2
  131. 131. URLs  y  Vistasfrom django.conf.urls.defaults import *from mysite.views import dentro_deurlpatterns = patterns(,url(r^time/plus/(d{1,2})/$, dentro_de),)from django.http import HttpResponsefrom datetime import datetime, timedeltadef dentro_de(request, offset):offset = int(offset)dt = datetime.now() + timedelta(hours=offset)html = "En %i hora(s), serán las %s." % (offset, dt)return HttpResponse(html)urls.pyviews.pyEjemplo  2:    http://mysite.com/time/plus/2
  132. 132. ¡Recuerda!:  MVC
  133. 133. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  134. 134. Templates• Separan  la  lógica  de  presentación  a  una  capa  independiente.• Ficheros  independientes  (.html)• Lenguaje  independiente  (¡para  diseñadores!)
  135. 135. Templates• Se  basan  en  dos  *pos  de  objetos:  Template()  y  Context().• Un  objeto  Template()  con*ene  el  string  de  salida  que  queremos  devolver  en  el  HGpResponse  (normalmente  HTML),  pero  incluyendo  e*quetas  especiales  de  Django.• Un  objeto  Context()  con*ene  un  diccionario  con  los  valores  que  dan  contexto  a  una  plan*lla,  los  que  deben  usarse  para  renderizar  un  objeto  Template()."Bienvenido, {{ user }}."{user: alatar}Template:Context:"Bienvenido, alatar."
  136. 136. Templatesfrom django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimePLANTILLA = """<html><body>Son las {{ hora }}.</body></html>"""def hora_actual(request):now = datetime.now()t = Template(PLANTILLA)c = Context({hora: now})html = t.render(c)return HttpResponse(html)• Primera  aproximación  al  obje*vo:  Template  +  Context
  137. 137. Templates• Segunda  aproximación  al  obje*vo:  open(),  read(),  close()from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()fp = open(/home/django/templates/hora.html)t = Template(fp.read())fp.close()c = Context({hora: now})html = t.render(c)return HttpResponse(html)
  138. 138. Templates• Segunda  aproximación  al  obje*vo:  open(),  read(),  close()from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()fp = open(/home/django/templates/hora.html)t = Template(fp.read())fp.close()c = Context({hora: now})html = t.render(c)return HttpResponse(html)
  139. 139. Templates• Segunda  aproximación  al  obje*vo:  open(),  read(),  close()from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()fp = open(/home/django/templates/hora.html)t = Template(fp.read())fp.close()c = Context({hora: now})html = t.render(c)return HttpResponse(html)Boring  boilerplate  code!
  140. 140. Templates• Tercera  aproximación  al  obje*vo:  get_template()from django.http import HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()t = get_template(hora.html)c = Context({hora: now})html = t.render(c)return HttpResponse(html)TEMPLATE_DIRS = (/home/django/templates,)senngs.py
  141. 141. Templates• Tercera  aproximación  al  obje*vo:  get_template()TEMPLATE_DIRS = (/home/django/templates,)senngs.pyfrom django.http import HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()t = get_template(hora.html)c = Context({hora: now})html = t.render(c)return HttpResponse(html)
  142. 142. Templates• Tercera  aproximación  al  obje*vo:  get_template()TEMPLATE_DIRS = (/home/django/templates,)senngs.pyfrom django.http import HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()t = get_template(hora.html)c = Context({hora: now})html = t.render(c)return HttpResponse(html)S*ll  boring...
  143. 143. Templates• Obje*vo  alcanzado:  render()from django.shortcuts import renderfrom datetime import datetimedef hora_actual(request):now = datetime.now()return render(request, hora.html, {hora: now})
  144. 144. Templates• Obje*vo  alcanzado:  render()from django.shortcuts import renderfrom datetime import datetimedef hora_actual(request):now = datetime.now()return render(request, hora.html, {hora: now})Boring...?
  145. 145. Templates• Obje*vo  alcanzado:  render()from django.shortcuts import renderfrom datetime import datetimedef hora_actual(request):now = datetime.now()return render(request, hora.html, {hora: now})AWESOME!
  146. 146. Templates:  TipTEMPLATE_DIRS = (/home/django/templates,)senngs.pya)
  147. 147. Templates:  TipTEMPLATE_DIRS = (/home/django/templates,)senngs.py Reusable  apps?a)
  148. 148. Templates:  TipTEMPLATE_DIRS = (/home/django/templates,)senngs.py Reusable  apps?a)b)• La  carpeta  /templates  es  buscada  dentro  de  cada  app.• Conviene  incluir  una  carpeta  con  el  nombre  de  la  app  por  claridad.TEMPLATE_LOADERS = (django.template.loaders.filesystem.Loader,django.template.loaders.app_directories.Loader,)return render(request, website/index.html)Alterna*va  reu*lizable:
  149. 149. ¡Empieza  nuestro  primer  proyecto!a) Crear  la  app  dwiier.website.b)Incluir  la  app  en  sesngs.py.c) Definir  una  vista  para  la  URL  “/”  que  devuelva  el  texto:        “Welcome  to  dwiier!”:‣ /‣ timeline(request)
  150. 150. h@p://github.com/enjoydjango/dwi@er
  151. 151. Git
  152. 152. GitQuiero  ir  a...¿Donde  estoy?1ª
  153. 153. Git$ git clone https://github.com/enjoydjango/dwitter.git$ git checkout -t origin/step-01-viewsQuiero  ir  a...$ git branch¿Donde  estoy?$ git checkout step-01-views1ª
  154. 154. GitIgnorar  todos  los  cambios  **  Si  no  habéis  commiteado  nada
  155. 155. Git$ git reset --hard HEAD$ git clean -fdIgnorar  todos  los  cambios  **  Si  no  habéis  commiteado  nada
  156. 156. h@p://github.com/enjoydjango/dwi@er
  157. 157. Tarea:  URLs  y  Vistasa) Implementar  la  vista  timeline()  para  que  renderice  un  Hmeline  de  twiier  en  una  template  index.html  a  parHr  de  datos  hardcodeados  en  un  diccionario.  h@p://bit.ly/diccionario-­‐tweets
  158. 158. Templates  en  detalle•  Si,  otro  sistema  de  templates•  Smarty,  Tiles,  ClearSilver  ...  •Describen  cuál  va  a  ser  el  resultado  que  ven  los  usuarios.•  Desacoplado  de  Python  (  Diseñadores  muy  lejos  de  Python  )•  HTML  (o  no)...  con  esteroides.•  Muy  sencillo  de  aprender•  KISS:  Keep  It  Simple,  Stupid•  Muy  sencillo  de  extender
  159. 159. Filoso]a  y  Limitaciones•  La  sintaxis  debe  estar  desacoplada  del  HTML/XML.•  Los  diseñadores  saben  HTML.•  Los  diseñadores  no  saben  Python.•  No  consiste  en  inventarse  un  lenguaje.•  Una  variable  no  puede  cambiar  el  valor  de  una  variable.•  Una  template  no  puede  ejecutar  código  Python.
  160. 160. Templates:  {{}}<html><head>Ejemplo templates</head><body>Hola, {{ username }}.</body></html>{username: juan}<html><head>Ejemplo templates</head><body>Hola, juan.</body></html>
  161. 161. Filters  y  Tags
  162. 162. Filters  y  Tags
  163. 163. Filters  y  Tags{{ varible|filter }}filter
  164. 164. Filters  y  Tags{{ varible|filter }}filter{% tag var1 var2 %}inline  tag
  165. 165. Filters  y  Tags{{ varible|filter }}filter{% tag var1 var2 %}inline  tag{% tag var1 %}...{% endtag %}block  tag
  166. 166. Templates:  tags  {%  %}
  167. 167. Templates:  tags  {%  %}{% comment %} Bu! {% endcomment %}comment
  168. 168. Templates:  tags  {%  %}{% comment %} Bu! {% endcomment %}commentfor {% for elemento in lista %}<li>{{ elemento }}<li>{% endfor %}
  169. 169. Templates:  tags  {%  %}{% comment %} Bu! {% endcomment %}commentfor {% for elemento in lista %}<li>{{ elemento }}<li>{% endfor %}if {% if username == "Juan" %}Hola Juan, me gustas!{% else %}Hola {{ username }},{% endif %}== != > < >= <=in and or not
  170. 170. Templates:  tags  {%  %}
  171. 171. Templates:  tags  {%  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor %}
  172. 172. Templates:  tags  {%  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor %}include {% include "foo/bar.html" %}
  173. 173. Templates:  tags  {%  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor %}include {% include "foo/bar.html" %}forloop {% for elemento in lista %}<li>{{ forloop.counter }}.{{ elemento }}<li>{% endfor %}
  174. 174. Templates:  tags  {%  %}cycle {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% endfor %}include {% include "foo/bar.html" %}forloop {% for elemento in lista %}<li>{{ forloop.counter }}.{{ elemento }}<li>{% endfor %}empty {% for elemento in lista %}<li class="{% cycle rojo azul %}">{{ elemento }}<li>{% empty %}Sin elementos.{% endfor %}
  175. 175.  Tarea:  Tagsa) UHlizar  tags  para  que  el  Hmeline  se  muestre  con  el  siguiente  formato:• <username>:  <tweet>  <Hmestamp>• <username>:  <tweet>  <Hmestamp>• ...
  176. 176.  Tarea:  Tags  avanzadosa) Hacer  que  el  Hmeline  muestre  el  mensaje  “No  hay  tweets.”  si  el  diccionario  recibido  está  vacío.
  177. 177. Templates:  Filters<html><head>Ejemplo templates</head><body>Hola, {{ username|title }}.</body></html>{username: juan}<html><head>Ejemplo templates</head><body>Hola, Juan.</body></html>/tle
  178. 178. Templates:  Filters
  179. 179. Templates:  Filters{username: Juan es majo}{{ username|length }}length 12
  180. 180. Templates:  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo
  181. 181. Templates:  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slugify }}slugify juan-es-majo
  182. 182. Templates:  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slugify }}slugify juan-es-majo{{ username|wordcount }}wordcount 3
  183. 183. Templates:  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slugify }}slugify juan-es-majo{{ username|upper }}upper JUAN ES MAJO{{ username|wordcount }}wordcount 3
  184. 184. Templates:  Filters{username: Juan es majo}{{ username|length }}length 12{{ username|cut }}cut Juanesmajo{{ username|slugify }}slugify juan-es-majo{{ username|upper }}upper JUAN ES MAJO{{ username|wordcount }}wordcount 3{{ username|default:”Desconocido” }}default{username: None}Desconocido
  185. 185. Templates:  Filters
  186. 186. Templates:  Filters{username: Juan es <b>majo, guapo y <em>listo</em></b>}{{ username|striptags }}striptagsJuan es majo guapo y listo
  187. 187. Templates:  Filters{username: Juan es <b>majo, guapo y <em>listo</em></b>}{{ username|striptags }}striptagsJuan es majo guapo y listo{{ username|truncatewords_html:4 }}truncatewords_htmlJuan es <b>majo guapo</b> ...
  188. 188. Templates:  Filters{username: Juan es <b>majo, guapo y <em>listo</em></b>}{{ username|striptags }}striptagsJuan es majo guapo y listo{{ username|truncatewords_html:4 }}truncatewords_htmlJuan es <b>majo guapo</b> ...{{ username|removetags:”em a br” }}removetagsJuan es <b>majo guapo y listo</b>
  189. 189. Templates:  Filters
  190. 190. Templates:  Filters{url: Visitad http://www.djangoproject.com}{{ url|urlize }}urlizeVisitad <a href=”http://www.djangoproject.com”> http://www.djangoproject.com </a>
  191. 191. Templates:  Filters{url: Visitad http://www.djangoproject.com}{{ url|urlize }}urlizeVisitad <a href=”http://www.djangoproject.com”> http://www.djangoproject.com </a>{{ url|urlizetrunc:16 }}urlizetruncVisitad <a href=”http://www.djangoproject.com”> http://www.djang...</a>
  192. 192. Templates:  Filters{lista: [States, [Kansas, [Lawrence, Topeka], Illinois]]}
  193. 193. Templates:  Filters{lista: [States, [Kansas, [Lawrence, Topeka], Illinois]]}{{ lista|unordered_list }}unordered_list<li>States<ul><li>Kansas<ul><li>Lawrence</li><li>Topeka</li></ul></li><li>Illinois</li></ul></li>
  194. 194. Templates:  Filters
  195. 195. Templates:  Filters{value: 123456789}{{ value|add:”1” }}add 123456790
  196. 196. Templates:  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB
  197. 197. Templates:  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB{date: datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }{{ date|date:”d M Y” }}date 11 Sep 2010
  198. 198. Templates:  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB{date: datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }{{ date|date:”d M Y” }}date 11 Sep 2010{{ date|timesince }}/mesince 4 days, 6 hours
  199. 199. Templates:  Filters{value: 123456789}{{ value|add:”1” }}add 123456790{{ value|filesizeformat }}filesizeformat 117.7MB{date: datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }{{ date|date:”d M Y” }}date 11 Sep 2010{{ date|timesince }}/mesince 4 days, 6 hours{{ date|timeuntil }}/meun/l 1 days, 6 hours
  200. 200. Tarea:  Filtersa) Añadir  a  cada  tweet  del  Hmeline  el  Hempo  transcurrido:• <username>:  <tweet><n>  seconds  ago• <username>:  <tweet><n>  minutes  ago• ...
  201. 201. Tarea:  Filtersb)Formatear  las  publicaciones  de  HOYGANs  convirHendo  el  texto  a  minúsculas  capitalizadas:‣“HOYGAN  NESESITO  QUE  MAYUDEN  A  HASER  UN  PROGRAMA  EN  DJANGO  GRASIAS  DE  ANTEBRASO”‣“Hoygan  necesito  que  mayuden  a  haser  un  programa  en  django  grasias  de  antebraso”  
  202. 202. Tarea:  Filtersc) Conseguir  que  todas  las  urls  que  aparezcan  en  los  tweets  se  conviertan  en  enlaces  <a  href=...  />  de  HTML.
  203. 203. Herencia  de  Templatesbase.html <html><head><title>Mi página personal</title></head><body>{% block content %}Contenido por defecto.{% endblock %}</body></html>hija.html {% extends "base.html" %}{% block content %}Hola desde la portada.{% endblock %}
  204. 204. Tarea:  Herencia  de  templatesa) Descargar  nuestra  template  base.html.b)Incluirla  en  vuestra  app.c) Hacer  que  vuestro  index.html  herede  de  base.html  y  exHenda  el  bloque  ‘content’  con  su  contenido.  h@p://bit.ly/base-­‐html-­‐template
  205. 205. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  206. 206. Modelos
  207. 207. ¿SQL?
  208. 208. Ejemplo  SQLdef book_list(request):try:db = MySQLdb.connect(user=me, db=mydb,passwd=secret, host=localhost)cursor = db.cursor()cursor.execute(SELECT nama FROM books ORDER BY name)names = []for row in cursor.fetchall()names.append(row[0])db.close()except:return render_to_response(500.html)return render_to_response(book_list.html, {names:names})
  209. 209. Ejemplo  SQLdef book_list(request):try:db = MySQLdb.connect(user=me, db=mydb,passwd=secret, host=localhost)cursor = db.cursor()cursor.execute(SELECT nama FROM books ORDER BY name)names = []for row in cursor.fetchall()names.append(row[0])db.close()except:return render_to_response(500.html)return render_to_response(book_list.html, {names:names})123456
  210. 210. 12  lineas  de  Python...  ¬_¬
  211. 211. ORM  (Object-­‐RelaHonal  mapping)
  212. 212. ORM  (Object-­‐RelaHonal  mapping)
  213. 213. Ejemplo  ORMdef book_list(request):names = Books.objects.all().order_by(name)return render(request, book_list.html, {names:names})
  214. 214. Ejemplo  ORMdef book_list(request):names = Books.objects.all().order_by(name)return render(request, book_list.html, {names:names})1 2
  215. 215. Fucking  Ninjas!
  216. 216. Modelofrom django.db import modelsclass Books(models.Model):name = models.CharField(blank=True, max_length=100)created = models.DateTimeField(blank=False)available = models.BooleanField(default=True)•  Independencia  SGBD!•  Definimos  estructuras  de  información  genéricas.•  Definimos  restricciones  (notnull,  blank,  max_lenght...)•  Única  definición  del  modelo  (configuración,  mapeo  a  db)  
  217. 217. Modelofrom django.db import modelsclass Books(models.Model):name = models.CharField(blank=True, max_length=100)created = models.DateTimeField(blank=False)available = models.BooleanField(default=True)213456•  Independencia  SGBD!•  Definimos  estructuras  de  información  genéricas.•  Definimos  restricciones  (notnull,  blank,  max_lenght...)•  Única  definición  del  modelo  (configuración,  mapeo  a  db)  
  218. 218. Fucking  Awesome  Ninjas!
  219. 219. Tipos  de  Datos• AutoField• BigIntegerField• BooleanField• CharField• CommaSeparatedIntegerField• DateField• DateTimeField• DecimalField• EmailField• FileField• FilePathField• FloatField• ImageField• IntegerField• IPAdressField• NullBooleanField• PositiveIntegerField• PositiveSmallIntegerField• SlugField• SmallIntegerField• TextField• TimeField• URLField• XMLField• ForeingKey• ManyToManyField• OneToOneField
  220. 220. Tipos  de  Datos• AutoField• BigIntegerField• BooleanField• CharField• CommaSeparatedIntegerField• DateField• DateTimeField• DecimalField• EmailField• FileField• FilePathField• FloatField• ImageField• IntegerField• IPAdressField• NullBooleanField• PositiveIntegerField• PositiveSmallIntegerField• SlugField• SmallIntegerField• TextField• TimeField• URLField• XMLField• ForeingKey• ManyToManyField• OneToOneField
  221. 221. Propiedades  de  las  Field• null (True|Flase)• blank (True|False)• choices (lista)• default (valor)• editable (True|False)• help_text (String)• unique (True|False)• primary_key• unique_for_date• unique_for_month• unique_for_year
  222. 222. Propiedades  de  las  Field• null (True|Flase)• blank (True|False)• choices (lista)• default (valor)• editable (True|False)• help_text (String)• unique (True|False)• primary_key• unique_for_date• unique_for_month• unique_for_year
  223. 223. ¿Es  magia?  No.BEGIN;CREATE TABLE "website_books" ("id" integer NOT NULL PRIMARY KEY,"name" varchar(100) NOT NULL,"created" datetime NOT NULL,"available" bool NOT NULL);COMMIT;BEGIN;CREATE TABLE "website_books" ("id" serial NOT NULL PRIMARY KEY,"name" varchar(100) NOT NULL,"created" timestamp with time zone NOT NULL,"available" boolean NOT NULL);COMMIT;
  224. 224. ¿Es  magia?  No.$ python manage.py sqlall websiteBEGIN;CREATE TABLE "website_books" ("id" integer NOT NULL PRIMARY KEY,"name" varchar(100) NOT NULL,"created" datetime NOT NULL,"available" bool NOT NULL);COMMIT;BEGIN;CREATE TABLE "website_books" ("id" serial NOT NULL PRIMARY KEY,"name" varchar(100) NOT NULL,"created" timestamp with time zone NOT NULL,"available" boolean NOT NULL);COMMIT;
  225. 225. ¿Es  magia?  No.•  Nombres  de  tablas  generados  automáHcamente.•  <app_name>_lower(<model_name>)•  id  como  Primary  Key  (Personalizable)•  Las  Foreing  Key  terminan  en  _id  (Personalizable)•  Los  Hpos  de  datos  se  ajustan  en  función  del  SGBD
  226. 226. Configurar  seyngs.pyDATABASES = {default: {ENGINE: django.db.backends.,NAME: ,USER: ,PASSWORD: ,HOST: ,PORT: ,}}postgresql_psycopg2,postgresql, mysql,sqlite3 or oracle.
  227. 227. Configurar  seyngs.pyDATABASES = {default: {ENGINE: django.db.backends.,NAME: ,USER: ,PASSWORD: ,HOST: ,PORT: ,}}123postgresql_psycopg2,postgresql, mysql,sqlite3 or oracle.
  228. 228. Creando  Tablas•  Crea  las  tablas  para  todos  los  modelos  de  las  apps  instaladas  en  el  fichero  sesngs.py•  No  actualiza  esquemas  si  la  tabla  existe.•  Eliminar  tabla  y  volver  a  ejecutar  syncdb
  229. 229. Creando  Tablas$ python manage.py syncdb•  Crea  las  tablas  para  todos  los  modelos  de  las  apps  instaladas  en  el  fichero  sesngs.py•  No  actualiza  esquemas  si  la  tabla  existe.•  Eliminar  tabla  y  volver  a  ejecutar  syncdb
  230. 230. Nuestro  primer  modeloa)Crear  modelo  Tweetb)Configurar  sesngs.pyc) Ver  el  SQL  generado  con  sqlall
  231. 231. syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating table auth_messageCreating table django_content_typeCreating table django_sessionCreating table django_siteCreating table website_tweetYou just installed Djangos auth system, which means you dont have anysuperusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use neo): adminE-mail address: user@example.comPassword:Password (again):Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet model
  232. 232. syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating table auth_messageCreating table django_content_typeCreating table django_sessionCreating table django_siteCreating table website_tweetYou just installed Djangos auth system, which means you dont have anysuperusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use neo): adminE-mail address: user@example.comPassword:Password (again):Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet modeldjango.contrib.auth
  233. 233. ¿Cuantos  sistemas  de  AutenHcación  habéis  programado?
  234. 234. ¿Alguno  era  mejor  que  el  anterior?  ;-­‐)
  235. 235. contrib.auth  puede  ser  el  úlHmo  :D
  236. 236. syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating table auth_messageCreating table django_content_typeCreating table django_sessionCreating table django_siteCreating table website_tweetYou just installed Djangos auth system, which means you dont have anysuperusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use neo): adminE-mail address: user@example.comPassword:Password (again):Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet modelwebsite.tweet
  237. 237. syncdb$ python manage.py syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating table auth_messageCreating table django_content_typeCreating table django_sessionCreating table django_siteCreating table website_tweetYou just installed Djangos auth system, which means you dont have anysuperusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use neo): adminE-mail address: user@example.comPassword:Password (again):Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet modeldjango.contrib.auth
  238. 238. BD  Lista  para  usarse
  239. 239. BD  Lista  para  usarse
  240. 240. Nuestro  primer  modeloa)Hacer  syncdb
  241. 241. Previo:  Clases  del  ORMts = Publisher.objects.all()ModelManagerQuerySet
  242. 242. INSERT
  243. 243. INSERT>>> p = Publisher(... name=Apress,... address=2855 Telegraph Avenue,... city=Berkeley,... state_province=CA,... country=U.S.A.,... website=http://www.apress.com/)>>> p.save()a)o = Model(...) o.save()
  244. 244. INSERT>>> p = Publisher.objects.create(... name=OReilly,... address=10 Fawcett St.,... city=Cambridge,... state_province=MA,... country=U.S.A.,... website=http://www.oreilly.com/)>>> p = Publisher(... name=Apress,... address=2855 Telegraph Avenue,... city=Berkeley,... state_province=CA,... country=U.S.A.,... website=http://www.apress.com/)>>> p.save()a)o = Model(...) o.save()manager.create(...)b)
  245. 245. UPDATE
  246. 246. UPDATE>>> ...>>> p.id52>>> p.name = Apress Publishing>>> p.save()o.save()1
  247. 247. UPDATE>>> Publisher.objects.all().update(country=USA)2>>> ...>>> p.id52>>> p.name = Apress Publishing>>> p.save()o.save()queryset.update(...)1n
  248. 248. DELETE
  249. 249. DELETE>>> ...>>> p.id52>>> p.delete()o.delete()1
  250. 250. DELETE>>> ps = Publisher.objects.all()>>> ps.delete()>>> ...>>> p.id52>>> p.delete()o.delete()queryset.delete()1n
  251. 251. SELECT  de  1  resultado
  252. 252. SELECT  de  1  resultado>>> Publisher.objects.get(name="Apress")<Publisher: Apress>.get(...)
  253. 253. SELECT  de  1  resultado>>> Publisher.objects.get(name="Apress")<Publisher: Apress>.get(...)>>> Publisher.objects.get(name="Anaya")Traceback (most recent call last):...DoesNotExist: Publisher matching query does not exist.
  254. 254. SELECT  de  1  resultado>>> Publisher.objects.get(name="Apress")<Publisher: Apress>.get(...)>>> Publisher.objects.get(country="U.S.A.")Traceback (most recent call last):...MultipleObjectsReturned: get() returned more than one Publisher --it returned 2! Lookup parameters were {country: U.S.A.}>>> Publisher.objects.get(name="Anaya")Traceback (most recent call last):...DoesNotExist: Publisher matching query does not exist.
  255. 255. SELECT  de  N  resultados
  256. 256. SELECT  de  N  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()
  257. 257. SELECT  de  N  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[<Publisher: Apress>].filter(...)
  258. 258. SELECT  de  N  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[<Publisher: Apress>].filter(...)>>> Publisher.objects.exclude(country="U.S.A.", state_province="CA")[<Publisher: OReilly>].exclude(...)
  259. 259. SELECT  de  N  resultados>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: OReilly>].all()>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[<Publisher: Apress>].filter(...)>>> Publisher.objects.exclude(country="U.S.A.", state_province="CA")[<Publisher: OReilly>].exclude(...)¡Devuelven  QuerySets,  no  listas!
  260. 260. get(),  filter()  y  exclude()
  261. 261. get(),  filter()  y  exclude()Modelo.objects.filter(campo1="valor1", campo2="valor2")Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=)
  262. 262. get(),  filter()  y  exclude()Modelo.objects.filter(campo1="valor1", campo2="valor2")Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=)campo__exact=campo__iexact=campo__contains=campo__icontains=campo__isnull=T|Fcampo__day=31campo__gt=0campo__gte=0campo__lt=0campo__lte=0campo__in=[ ,]campo__month=12campo__startswith=campo__istartswith=campo__endswith=campo__iendswith=campo__range=( ,)campo__year=2010
  263. 263. ORDER  BY
  264. 264. ORDER  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)
  265. 265. ORDER  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)>>> Publisher.objects.order_by("-name")[<Publisher: OReilly>, <Publisher: Apress>]
  266. 266. ORDER  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)>>> Publisher.objects.order_by("-name")[<Publisher: OReilly>, <Publisher: Apress>]>>> Publisher.objects.order_by("-name", "country")[<Publisher: OReilly>, <Publisher: Apress>]MúlHples  campos:
  267. 267. ORDER  BY>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: OReilly>].order_by(...)>>> Publisher.objects.order_by("-name")[<Publisher: OReilly>, <Publisher: Apress>]>>> Publisher.objects.order_by("-name", "country")[<Publisher: OReilly>, <Publisher: Apress>]MúlHples  campos:¡También  devuelve  QuerySets!
  268. 268. Slicing
  269. 269. Slicing>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>[n:m]>>> Publisher.objects.order_by("name")[:2][<Publisher: Apress>, <Publisher: OReilly>]>>> Publisher.objects.order_by("name")[1:2][<Publisher: OReilly>]
  270. 270. Slicing>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>[n:m]>>> Publisher.objects.order_by("name")[:2][<Publisher: Apress>, <Publisher: OReilly>]>>> Publisher.objects.order_by("name")[1:2][<Publisher: OReilly>]LIMIT
  271. 271. Slicing>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>[n:m]>>> Publisher.objects.order_by("name")[:2][<Publisher: Apress>, <Publisher: OReilly>]>>> Publisher.objects.order_by("name")[1:2][<Publisher: OReilly>]LIMITOFFSET
  272. 272. Related  Objects
  273. 273. Related  ObjectsOneToOneFieldclass Coche(models.Model):motor = OneToOneField(Motor)class Motor(models.Model):...11
  274. 274. Related  ObjectsOneToOneFieldclass Coche(models.Model):motor = OneToOneField(Motor)class Motor(models.Model):...>>> c.motor<Motor: Motor object>¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros11
  275. 275. Related  ObjectsOneToOneFieldclass Coche(models.Model):motor = OneToOneField(Motor)class Motor(models.Model):...>>> c.motor<Motor: Motor object>>>> m.coche<Coche: Coche object>¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros Gracias  a  Django11
  276. 276. Related  Objects
  277. 277. Related  ObjectsForeignKeyFieldclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog)1n
  278. 278. Related  ObjectsForeignKeyFieldclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog)>>> p.blog<Blog: Blog object>>>> b.post_set.all()[<Post: Post object>, ...]¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros Gracias  a  Django1n
  279. 279. Related  Objects
  280. 280. Related  ObjectsManyToManyFieldclass Post(models.Model):tags = ManyToManyField(Tag)class Tag(models.Model):...nm
  281. 281. Related  ObjectsManyToManyFieldclass Post(models.Model):tags = ManyToManyField(Tag)class Tag(models.Model):...>>> p.tags.add(t1, t2)>>> p.tags.all()[<Tag: Tag object>, ...]>>> t.post_set.add(p1, p2)>>> t.post_set.all()[<Post: Post object>, ...]¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros Gracias  a  Djangonm
  282. 282. Related  Objects
  283. 283. Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inversoclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog, related_name=posts)1n
  284. 284. Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inversoclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog, related_name=posts)>>> p.blog<Blog: Blog object>>>> b.posts.all()[<Post: Post object>, ...]Gracias  a  nosotros Gracias  a  Django1n
  285. 285. Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inversoclass Blog(models.Model):...class Post(models.Model):blog = ForeignKeyField(Blog, related_name=posts)>>> p.blog<Blog: Blog object>>>> b.posts.all()[<Post: Post object>, ...]Gracias  a  nosotros Gracias  a  Django1nCuando  haya  2  relaciones  entre  2  modelos,  será  obligatorio
  286. 286. Y  la  guinda  final:  ¡Todo  es  LAZY!
  287. 287. Laziness
  288. 288. Laziness• Las  consultas  sólo  se  ejecutarán  cuando  realmente  se  necesite  obtener  los  objetos.  En  las  siguientes  situaciones:• Iteraciones• Slicing• Serialización• repr()• len() !!!• list()• bool()for p in Publisher.objects.all():Publisher.objects.filter(country=USA)[0][Caché][<Publisher: Publisher object>]len(Publisher.objects.all())list(Publisher.objects.all())if Publisher.objects.filter(country=USA):
  289. 289. Nota:  __unicode__()
  290. 290. Nota:  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
  291. 291. Nota:  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
  292. 292. Nota:  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
  293. 293. Nota:  __unicode__()class Publisher(models.Model):...def __unicode__(self):return self.name>>> Publisher.objects.all()[<Publisher: Publisher object>]
  294. 294. Nota:  __unicode__()class Publisher(models.Model):...def __unicode__(self):return self.name>>> Publisher.objects.all()[<Publisher: Publisher object>]>>> Publisher.objects.all()[<Publisher: Apress>]
  295. 295. Usando  el  ORMa)Insertar  varios  Tweets  desde  la  shell.b)Modificar  views.timeline  para  que  uHlice  los  Tweets  reales  de  la  BD.
  296. 296. Usando  el  ORMc) Implementar  la  vista  tweet_page()  como  permalink  de  un  tweet:‣ URL:    tweet/<tweet_id>/‣ View:    tweet_page‣ Template:    tweet_page.html    (Descargar)d)Lanzar  Http404  si  no  existe  el  tweet_id.e)shortcut!:  get_object_or_404()  h@p://bit.ly/tweet-­‐page
  297. 297. Profiles
  298. 298. Profile•  Problema:  El  modelo  User  de  django.contrib.auth  no  puede  contener  toda  la  información  que  necesitamos.•  Username,  Password,  Name....  y  poco  más.•  Solución:  Definir  un  Profile  (Un  Modelo  Agregado)  para  guardar  esa  información.
  299. 299. Profilemodels.py
  300. 300. Profileclass Profile(models.Model):user = models.OneToOneField(User, unique=True)bio = models.CharField(blank=True, max_length=200)...models.py•  Cada  objeto  User  de  django.contrib.auth  dispondrá  de  un  atributo  profile  que  nos  permiHrá  acceder  al  Profile.
  301. 301. Profile•Donde  tengamos  el  User  tendremos  el  Profile.•Donde  tengamos  el  Profile,  tendremos  el  User.
  302. 302. Profile>>> from django.contrib.auth.models import User>>> u = User.objects.get(id=1)>>> type(u)<class django.contrib.auth.models.User>>>> type(u.profile)<class website.models.Profile>•Donde  tengamos  el  User  tendremos  el  Profile.•Donde  tengamos  el  Profile,  tendremos  el  User.
  303. 303. 1  User  =  1  Profile  ¿Cuándo  se  crea  un  User?
  304. 304. Signals•  Django  incorpora  un  dispacher  de  señales  para  ayudar  a  crear  aplicaciones  reuHlizables.•  Permite  subscribirnos  a  “eventos”  a  lo  largo  de  todo  el  framework  y  actuar  frente  a  ellos  (¡Observer-­‐Observable!).•  Señales  interesantes:• pre_save, post_save• pre_delete, post_delete• m2m_changed• request_started, request_finished  h@p://docs.djangoproject.com/en/dev/ref/signals/
  305. 305. Signals
  306. 306. Signalsdef create_user_profile(sender, instance, created, **kwargs):if created:Profile.objects.create(user=instance)from django.db.models.signals import post_savepost_save.connect(create_user_profile, sender=User)123Puede  estar  en  cualquier  app  de  nuestro  proyecto.Se  recomienda  models.py
  307. 307. Users  en  dwiiera)Crear  el  modelo  Profileb)Crear  signal  para  agregar  un  objeto  Profile  a  cada  objeto  User  creado.c) Eliminar  BD.d)Hacer  syncdb
  308. 308. Followers
  309. 309. Profilemodels.py
  310. 310. Profileclass Profile(models.Model):user = models.OneToOneField(User, unique=True)bio = models.CharField(blank=True, max_length=200)followers = models.ManyToManyField("self", blank=True,symmetrical=False,related_name="following")models.py•  m2m  symmetrical  (por  defecto)•  Si  yo  te  sigo  a  H,  tú  me  sigues  a  mi.•  related_name  (en  este  caso)•  Limpieza  y  evitar  profile_set
  311. 311. Users  en  dwiiera)Añadir  ManyToMany  para  los  followers.b)Eliminar  BD.c) Hacer  syncdb
  312. 312. 1,2,3  Borrar  la  BD....  1,2,3...  Borrar  la  BD
  313. 313. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  314. 314. CRUD:  Create,  Retrieve,  Update  &  Delete
  315. 315. django.contrib.admin123
  316. 316. django.contrib.admin123
  317. 317. django.contrib.admin1
  318. 318. Django  admin:  Instalaciónfrom django.conf.urls.defaults import *# Uncomment the next two lines to enable the admin:# from django.contrib import admin# admin.autodiscover()urlpatterns = patterns(,...# url(r^admin/, include(admin.site.urls)),...)12urls.py
  319. 319. Django  admin:  Instalaciónfrom django.conf.urls.defaults import *# Uncomment the next two lines to enable the admin:from django.contrib import adminadmin.autodiscover()urlpatterns = patterns(,...url(r^admin/, include(admin.site.urls)),...)12urls.py
  320. 320. Django  admin:  InstalaciónINSTALLED_APPS = (django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.sites,...)senngs.py
  321. 321. Django  admin:  InstalaciónINSTALLED_APPS = (django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.sites,django.contrib.admin,...)senngs.py1
  322. 322. Actualizando  la  BD
  323. 323. Actualizando  la  BD$ python manage.py syncdbCreating table django_admin_logInstalling index for admin.LogEntry modelAdmin  lista  para  usar
  324. 324. ¿Y  nuestra  app??
  325. 325. ¿Y  nuestra  app?
  326. 326. admin.py• Cada  app  debe  de  tener  el  suyo.• Define  qué  modelos  serán  visibles  desde  el  admin  y  permite  personalizar  su  aspecto.from django.contrib import adminfrom website.models import Tweetclass TweetAdmin(admin.ModelAdmin):list_display = (id,user,message,timestamp)admin.site.register(Tweet, TweetAdmin)
  327. 327. Instalar  Admina)Configurar  urls.pyb)Configurar  sesngs.pyc) Hacer  syncdb
  328. 328. Instalar  Admind)Comprobar  que  no  están  Tweet  y  Profilee)Añadir  admin.pyf) Probar  Administración.
  329. 329. Fixtures
  330. 330. Fixtures•  Es  muy  aburrido  crear  juegos  de  datos  cada  vez  que  se  elimina  una  tabla  /  BD.•  No  nos  gustan  las  cosas  aburridas.•  Ficheros  (json/xml/yaml)  para  inicializar  una  Tabla.•  Pueden  crearse  una  vez  dispongamos  de  la  información:
  331. 331. Fixtures•  Es  muy  aburrido  crear  juegos  de  datos  cada  vez  que  se  elimina  una  tabla  /  BD.•  No  nos  gustan  las  cosas  aburridas.•  Ficheros  (json/xml/yaml)  para  inicializar  una  Tabla.•  Pueden  crearse  una  vez  dispongamos  de  la  información:python manage.py dumpdata <appName appName appName.model ...>
  332. 332. Fixtures•  Es  muy  aburrido  crear  juegos  de  datos  cada  vez  que  se  elimina  una  tabla  /  BD.•  No  nos  gustan  las  cosas  aburridas.•  Ficheros  (json/xml/yaml)  para  inicializar  una  Tabla.•  Pueden  crearse  una  vez  dispongamos  de  la  información:python manage.py dumpdata <appName appName appName.model ...>•  Se  cargan  uHlizando:python manage.py loaddata <fixture fixture ...>•  Si  se  llaman  iniAal_data  y  están  dentro  de  la  carpeta  fixtures  de  la  app,  se  cargan  al  ahcer  el  syncdb.
  333. 333. Tarea:  Avance  en  dwiiera)Implementar  la  vista  user_page()  para  ofrecer  un  perfil  de  usuario  con  su  Hmeline  personal:‣ URL:    user/<username>/‣ View:    user_page‣ Template:    user_page.html  h@p://bit.ly/user-­‐page
  334. 334. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  335. 335. Formularios
  336. 336. Clases  involucradas
  337. 337. Clases  involucradasWidget Componente  visual  equivalente  a  HTMLTextInputCheckboxInput<input type=text...><input type=checkbox...>
  338. 338. Clases  involucradasWidget Componente  visual  equivalente  a  HTMLTextInputCheckboxInput<input type=text...><input type=checkbox...>Field Lógica  de  un  campo,  asociado  a  un  WidgetEmailFieldIPAddressFieldwidget, initial, error, ...
  339. 339. Clases  involucradasWidget Componente  visual  equivalente  a  HTMLTextInputCheckboxInput<input type=text...><input type=checkbox...>Field Lógica  de  un  campo,  asociado  a  un  WidgetEmailFieldIPAddressFieldwidget, initial, error, ...Form Conjunto  de  Fields  de  un  formularioContactForm [nombre, email, telefono, mensaje, ...]
  340. 340. Fields
  341. 341. Fields■ BooleanField■ CharField■ ChoiceField■ TypedChoiceField■ DateField■ DateTimeField■ DecimalField■ EmailField■ FileField■ FilePathField■ FloatField■ ImageField■ IntegerField■ IPAddressField■ MultipleChoiceField■ NullBooleanField■ RegexField■ SlugField■ TimeField■ URLField■ ComboField■ MultiValuefield■ SplitDateTimeField■ ModelChoiceField■ ModelMultipleChoiceField
  342. 342. Fields■ BooleanField■ CharField■ ChoiceField■ TypedChoiceField■ DateField■ DateTimeField■ DecimalField■ EmailField■ FileField■ FilePathField■ FloatField■ ImageField■ IntegerField■ IPAddressField■ MultipleChoiceField■ NullBooleanField■ RegexField■ SlugField■ TimeField■ URLField■ ComboField■ MultiValuefield■ SplitDateTimeField■ ModelChoiceField■ ModelMultipleChoiceField
  343. 343. Creación  de  un  Formfrom django import formsclass ContactForm(forms.Form):subject = forms.CharField(max_length=100, label=Topic)email = forms.EmailField(required=False)message = forms.CharField(widget=forms.Textarea)• Paso  1/3:  Definición  del  formulario  en  forms.py
  344. 344. Creación  de  un  Form<html><body><h1>Contact us</h1>{% if form.errors %}<p style="color: red;">Please correct the error{{ form.errors|pluralize }} below.</p>{% endif %}<form action="" method="post"><table>{{ form.as_table }}</table><input type="submit" value="Submit"></form></body></html>• Paso  2/3:  Maquetación  del  formulario  en  su  template
  345. 345. Creación  de  un  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(request):if request.method == POST:form = ContactForm(request.POST)if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/)else:form = ContactForm()return render(request, contact_form.html, {form: form})• Paso  3/3:  Programación  de  la  vista  en  views.py
  346. 346. Creación  de  un  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(request):if request.method == POST:form = ContactForm(request.POST)if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/)else:form = ContactForm()return render(request, contact_form.html, {form: form})• Paso  3/3:  Programación  de  la  vista  en  views.pyPaiern
  347. 347. Creación  de  un  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(request):if request.method == POST:form = ContactForm(request.POST)if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/)else:form = ContactForm()return render(request, contact_form.html, {form: form})• Paso  3/3:  Programación  de  la  vista  en  views.pyPaiern
  348. 348. Creación  de  un  Formfrom django.shortcuts import renderfrom mysite.contact.forms import ContactFormdef contact(request):if request.method == POST:form = ContactForm(request.POST)if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/)else:form = ContactForm()return render(request, contact_form.html, {form: form})• Paso  3/3:  Programación  de  la  vista  en  views.pyPaiern
  349. 349. Validación  propiafrom django import formsclass ContactForm(forms.Form):subject = forms.CharField(max_length=100)email = forms.EmailField(required=False)message = forms.CharField(widget=forms.Textarea)def clean_message(self):message = self.cleaned_data[message]num_words = len(message.split())if num_words < 4:raise forms.ValidationError("Not enough words!")return messagePodemos  programar  validación  extra  asociada  a  cada  Field  del  formulario  escribiendo  un  método  clean_<fieldname>:
  350. 350. Validación  propiafrom django import formsclass ContactForm(forms.Form):subject = forms.CharField(max_length=100)email = forms.EmailField(required=False)message = forms.CharField(widget=forms.Textarea)def clean_message(self):message = self.cleaned_data[message]num_words = len(message.split())if num_words < 4:raise forms.ValidationError("Not enough words!")return messagePodemos  programar  validación  extra  asociada  a  cada  Field  del  formulario  escribiendo  un  método  clean_<fieldname>:
  351. 351. Maquetación  propia...<form action="" method="post"><div class="field">{{ form.subject.errors }}<label for="id_subject">Subject:</label>{{ form.subject }}</div><div class="field">{{ form.email.errors }}<label for="id_email">E-mail:</label>{{ form.email }}</div>...<input type="submit" value="Submit"></form>...Podemos  personalizar  la  maquetación  tanto  como  queramos,  prescindiendo  de  las  ayudas  de  form.as_table:<style type="text/css">ul.errorlist {...}.errorlist li {...}</style>Para  los  diseñadores:
  352. 352. Forms  a  parHr  de  Models:  El  COLMO  del  DRY
  353. 353. Forms  a  par/r  de  Modelsfrom django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)birth_date = models.DateField(blank=True, null=True)country = models.ModelChoiceField(Country)...from django import formsfrom books.models import Authorclass AuthorForm(forms.ModelForm):class Meta:model = Authorexclude = (country,)models.pyforms.py
  354. 354. Primer  Form  en  dwiiera)Crear  un  Form  que  permita  publicar  tweets  desde  Hmeline.html  al  usuario  que  esté  logueado  desde  django.contrib.admin  (no  tenemos  login  propio  de  momento).
  355. 355. Tarea:  Avance  en  dwiiera)Implementar  la  vista  users_list()  para  visualizar  la  lista  de  usuarios:‣ URL:    users/‣ View:    users_list‣ Template:    users_list.html    (Descargar)  h@p://bit.ly/users-­‐list
  356. 356. Índice1.Pythona. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzadaProyecto
  357. 357. Magia  avanzada
  358. 358. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas
  359. 359. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas
  360. 360. Views  avanzadasfrom django.conf.urls.defaults import *urlpatterns = patterns(,url(r^hello/$, mysite.views.hello),url(r^time/$, mysite.views.current_datetime),url(r^time/plus/(d{1,2})/$, mysite.views.hours_ahead),)El  primer  parámetro  de  pa@erns()  sirve  de  algo
  361. 361. Views  avanzadasfrom django.conf.urls.defaults import *urlpatterns = patterns(,url(r^hello/$, mysite.views.hello),url(r^time/$, mysite.views.current_datetime),url(r^time/plus/(d{1,2})/$, mysite.views.hours_ahead),)from django.conf.urls.defaults import *urlpatterns = patterns(mysite.views,url(r^hello/$, hello),url(r^time/$, current_datetime),url(r^time/plus/(d{1,2})/$, hours_ahead),)¡El  primer  parámetro  de  pa@erns()  sirve  de  algo!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×