504
Jorge Bas*da me@jorgebas*da.com @jorgebas*da Jaime Irurzun [email protected] @jaimeirurzun

Desarrollo web ágil con Python y Django

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 3: Desarrollo web ágil con Python y Django
Page 4: Desarrollo web ágil con Python y Django
Page 5: Desarrollo web ágil con Python y Django
Page 6: Desarrollo web ágil con Python y Django
Page 7: Desarrollo web ágil con Python y Django

Evaluación

Page 8: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 9: Desarrollo web ágil con Python y Django
Page 10: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 11: Desarrollo web ágil con Python y Django

• Legible

• Produc/vo

• Portable

• Extenso

• Integrable

• ...  y  Diver/do

Sintaxis  intuiHva  y  estricta

Entre  1/3  y  1/5  más  conciso  que  Java  o  C++

GNU/Linux,  Windows,  Mac  OS  X,  ...

Standard  Library,  Third  parHes

C,  C++,  Java,  .NET,  COM,  WS,  CORBA,  ...

Page 12: Desarrollo web ágil con Python y Django

Instalación

$ sudo apt-get install python

http://www.python.org/download/

Mountain  Lion  incluye  las  versiones:  2.5.6,    2.6.7, 2.7.2

Page 13: Desarrollo web ágil con Python y Django

El  Intérprete

Page 14: Desarrollo web ágil con Python y Django

El  Intérprete

$ python holamundo.py hola mundo!$

Modo  Batch

#!/usr/bin/env pythonprint "hola mundo!"

holamundo.py

Page 15: Desarrollo web ágil con Python y Django

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.py hola mundo!$

Modo  Batch

#!/usr/bin/env pythonprint "hola mundo!"

holamundo.py

Page 16: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 17: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

Page 18: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

Page 19: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

True Falsebool

Page 20: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

True Falsebool

'spam' "guido's" """n lines"""str

Page 21: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

True Falsebool

'spam' "guido's" """n lines"""str

[1, [2, 'three'], 4]list

Page 22: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

True Falsebool

'spam' "guido's" """n lines"""str

[1, [2, 'three'], 4]list

{'food': 'spam', 'taste': 'yum'}dict

Page 23: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

True Falsebool

'spam' "guido's" """n lines"""str

[1, [2, 'three'], 4]list

{'food': 'spam', 'taste': 'yum'}dict

(1, 'spam', 4, 'U')tuple

Page 24: Desarrollo web ágil con Python y Django

Tipos  de  datos

 h@p://docs.python.org/library/stdtypes.html

object

1234 3.1415int float35Llong

True Falsebool

'spam' "guido's" """n lines"""str

[1, [2, 'three'], 4]list

{'food': 'spam', 'taste': 'yum'}dict

(1, 'spam', 4, 'U')tuple

¡Tipado  

dinámico!

Page 25: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 26: Desarrollo web ágil con Python y Django

Operadores

 h@p://docs.python.org/library/operator.html

Page 27: Desarrollo web ágil con Python y Django

Operadores

numéricosa + b a - b a * b a / b

a % b -a +a a ** b

 h@p://docs.python.org/library/operator.html

Page 28: Desarrollo web ágil con Python y Django

Operadores

numéricosa + b a - b a * b a / b

a % b -a +a a ** b

comparadoresa < b a <= b a > b

a >= b a == b a != b

 h@p://docs.python.org/library/operator.html

Page 29: Desarrollo web ágil con Python y Django

Operadores

numéricosa + b a - b a * b a / b

a % b -a +a a ** b

comparadoresa < b a <= b a > b

a >= b a == b a != b

lógicos a or b a and b not a

 h@p://docs.python.org/library/operator.html

Page 30: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 31: Desarrollo web ágil con Python y Django

Usos  frecuentes:  list

Page 32: Desarrollo web ágil con Python y Django

Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1

Page 33: Desarrollo web ágil con Python y Django

Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1

>>> 2 in numsTrue

Page 34: Desarrollo web ágil con Python y Django

Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1

>>> nums.append(4)>>> print nums[1, 2, 3, 4]

>>> 2 in numsTrue

Page 35: Desarrollo web ágil con Python y Django

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

Page 36: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str

Page 37: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str>>> "Python mola"[1:4]'yth'

Page 38: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str>>> "Python mola"[1:4]'yth'

>>> "Python mola".find("mola")7

Page 39: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str>>> "Python mola"[1:4]'yth'

>>> "Python mola".find("mola")7

>>> "Python mola".replace("Python", "PHP no")'PHP no mola'

Page 40: Desarrollo web ágil con Python y Django

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']

Page 41: Desarrollo web ágil con Python y Django

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"

Page 42: Desarrollo web ágil con Python y Django

Usos  frecuentes:  dict

Page 43: Desarrollo web ágil con Python y Django

Usos  frecuentes:  dict>>> user = {'nick': 'neo', 'phone': '5555'}>>> user.keys()['nick', 'phone']>>> user.values()['neo', '5555']

Page 44: Desarrollo web ágil con Python y Django

Usos  frecuentes:  dict>>> user = {'nick': 'neo', 'phone': '5555'}>>> user.keys()['nick', 'phone']>>> user.values()['neo', '5555']

>>> user['nick']'neo'

>>> user.get('age', 26)26

Page 45: Desarrollo web ágil con Python y Django

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

Page 46: Desarrollo web ágil con Python y Django

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}

Page 47: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str  %

Page 48: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str  %

>>> "%s es muy sabio" % "Hycker"'Hycker es muy sabio'

Page 49: Desarrollo web ágil con Python y Django

Usos  frecuentes:  str  %

>>> "%s es muy sabio" % "Hycker"'Hycker es muy sabio'

>>> "%s sabe %i idiomas" % ("Hycker", 5)'Hycker sabe 5 idiomas'

Page 50: Desarrollo web ágil con Python y Django

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 % v'Hycker sabe 5 idiomas'

Page 51: Desarrollo web ágil con Python y Django

juego/ __init__.py bonus/ __init__.py estrella.py moneda.py planta.py ... personajes/ __init__.py mario.py luigi.py princesa.py ... enemigos/ __init__.py seta.py tortuga.py bomba.py ...

Módulos1. Un  módulo  es  un  fichero  .py

2. Los  módulos  pueden  

organizarse  en  paquetes.

3. Un  paquete  es  una  carpeta  

que  conHene  un  fichero  con  

nombre  __init__.py

Page 52: Desarrollo web ágil con Python y Django

juego/ __init__.py bonus/ __init__.py estrella.py moneda.py planta.py ... personajes/ __init__.py mario.py luigi.py princesa.py ... enemigos/ __init__.py seta.py tortuga.py bomba.py ...

Módulos1. Un  módulo  es  un  fichero  .py

2. Los  módulos  pueden  

organizarse  en  paquetes.

3. Un  paquete  es  una  carpeta  

que  conHene  un  fichero  con  

nombre  __init__.py

1

23

Page 53: Desarrollo web ágil con Python y Django

Módulos

En  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

Page 54: Desarrollo web ágil con Python y Django

Módulosjuego/ __init__.py bonus/ __init__.py estrella.py moneda.py planta.py ... personajes/ __init__.py mario.py luigi.py princesa.py ... enemigos/ __init__.py seta.py tortuga.py bomba.py ...

Page 55: Desarrollo web ágil con Python y Django

Módulosjuego/ __init__.py bonus/ __init__.py estrella.py moneda.py planta.py ... personajes/ __init__.py mario.py luigi.py princesa.py ... enemigos/ __init__.py seta.py tortuga.py bomba.py ...

>>> from juego.personajes.mario import Mario>>> Mario()

>>> from juego.personajes.mario import *>>> Mario()

>>> from juego import personajes>>> personajes.mario.Mario()

Page 56: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 57: Desarrollo web ágil con Python y Django

{}Estructuras

Page 58: Desarrollo web ágil con Python y Django

{}Estructuras

Page 59: Desarrollo web ágil con Python y Django

>>> from __future__ import braces File "<stdin>", line 1 SyntaxError: not a chance

Identación

4  Espac/os  para  la  identación

Page 60: Desarrollo web ágil con Python y Django

>>> from __future__ import braces File "<stdin>", line 1 SyntaxError: not a chance

Identación

4  Espac/os  para  la  identaciónPEP 8

Page 61: Desarrollo web ágil con Python y Django

•  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/

Page 64: Desarrollo web ágil con Python y Django

Conversión  de  /pos

 h@p://docs.python.org/library/func/ons.html

Page 65: Desarrollo web ágil con Python y Django

Conversión  de  /pos

>>> int(1.3)1

 h@p://docs.python.org/library/func/ons.html

Page 66: Desarrollo web ágil con Python y Django

Conversión  de  /pos

>>> str(2)'2'

>>> int(1.3)1

 h@p://docs.python.org/library/func/ons.html

Page 67: Desarrollo web ágil con Python y Django

Conversión  de  /pos

>>> str(2)'2'

>>> int(1.3)1

>>> float(1)1.0

 h@p://docs.python.org/library/func/ons.html

Page 68: Desarrollo web ágil con Python y Django

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

Page 69: Desarrollo web ágil con Python y Django

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

Page 70: Desarrollo web ágil con Python y Django

Funciones  comunes

 h@p://docs.python.org/library/func/ons.html

Page 71: Desarrollo web ágil con Python y Django

Funciones  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4

 h@p://docs.python.org/library/func/ons.html

Page 72: Desarrollo web ágil con Python y Django

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

Page 73: Desarrollo web ágil con Python y Django

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

Page 74: Desarrollo web ágil con Python y Django

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

Page 75: Desarrollo web ágil con Python y Django

Funciones  interesantes

Son  sólo  un  ejemplo...

 h@p://docs.python.org/library/func/ons.html

Page 76: Desarrollo web ágil con Python y Django

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

Page 77: Desarrollo web ágil con Python y Django

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

Page 78: Desarrollo web ágil con Python y Django

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

Page 79: Desarrollo web ágil con Python y Django

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

Page 80: Desarrollo web ágil con Python y Django

Funciones  de  ayuda

Page 81: Desarrollo web ágil con Python y Django

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']

Page 82: Desarrollo web ágil con Python y Django

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 string Return those items of sequence for which function(item) is true. If function is None, return the items that are true. If sequence is a tuple or string, return the same type, else return a list.(END)

Page 83: Desarrollo web ágil con Python y Django

class Student(object): def __init__(self, name, age): self.name = name self.age = age def hello(self): return 'My name is %s' % self.name

Clases

s = Student("Jorge", 24)

camelCase

Page 84: Desarrollo web ágil con Python y Django

class Student(object): def __init__(self, name, age): self.name = name self.age = age def hello(self): return 'My name is %s' % self.name

1 2

3

4

5

Clases

s = Student("Jorge", 24)

camelCasePEP 8

Page 85: Desarrollo web ágil con Python y Django

El  operador  ()

• Es  importante  diferenciar:

funcion      vs      funcion()

Clase              vs        Clase()

• El  operador  ()  permite:

• Invocar  funciones:

• Instanciar  clases:

resultado = funcion()

objeto = Clase("param1")

Page 86: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 87: Desarrollo web ágil con Python y Django

$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

Page 88: Desarrollo web ágil con Python y Django

$count = 0;while ($count < 5) { echo "Number ".$count; $count+=1;}

count = 0while count < 5: print "Number %i" % count count+=1

Sentencias:  while

Page 89: Desarrollo web ágil con Python y Django

for ($i=0; $i < 5; $i++) { echo "Number ".$count;}

for i in range(4): print "Number %i" % count

Sentencias:  for

Page 90: Desarrollo web ágil con Python y Django

try { $result = 3 / 0;} catch (Exception $e) { echo "Division by Zero"}

try: result = 3 / 0except: print "Division by Zero"

Sentencias:  try-­‐except

Page 91: Desarrollo web ágil con Python y Django

Prueba  de  sentencias  en  consola

Page 92: Desarrollo web ágil con Python y Django

•  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

Page 93: Desarrollo web ágil con Python y Django

•  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

Page 94: Desarrollo web ágil con Python y Django

Ejemplo  PythonhGp://bit.ly/ejemplo-­‐python    

Page 95: Desarrollo web ágil con Python y Django

Ejercicio  PythonhGp://bit.ly/ejercicio-­‐python    

Page 96: Desarrollo web ágil con Python y Django

SolucioneshGp://bit.ly/ejercicio-­‐resuelto

hGp://bit.ly/ejercicio-­‐resuelto-­‐awesome

Page 97: Desarrollo web ágil con Python y Django
Page 98: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 99: Desarrollo web ágil con Python y Django

Evolución  de  la  Web

Desarrollo  Web

1ª  Generación 2ª  Generación 3ª  Generación

HTMLCGI

PHPASPJSP...

DjangoRails

Symfony...

Page 100: Desarrollo web ágil con Python y Django

Frameworks  web

Page 101: Desarrollo web ágil con Python y Django

Django:  Qué  y  dónde

Page 102: Desarrollo web ágil con Python y Django

•  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

Page 103: Desarrollo web ágil con Python y Django

•  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 in one, and only one, place. Redundancy is bad. Normalization is good.”“

Filoso]a

Page 104: Desarrollo web ágil con Python y Django

•  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/

Page 105: Desarrollo web ágil con Python y Django

La  comunidad

Page 106: Desarrollo web ágil con Python y Django

La  comunidad

• django-­‐users

23.000  miembros

• django-­‐developers

7.400  miembros

• djangoproject.com

+500.000  visitas  únicas  mensuales

Page 107: Desarrollo web ágil con Python y Django

¿Quién  usa  Django?

Page 108: Desarrollo web ágil con Python y Django

¿Quién  usa  Django?

Page 109: Desarrollo web ágil con Python y Django

1.  Instalación  Python

$ sudo apt-get install python

http://www.python.org/download/

Mountain  Lion  incluye  las  versiones:  2.5.6,  2.6.7, 2.7.2

Page 110: Desarrollo web ágil con Python y Django

Configurar  un  motor  de  Base  de  Datos:

•  Oficiales:  •  PostgreSQL•  MySQL

•  Oracle•  SQLite

•  Comunidad:  •  Sybase  SQL  Anywhere•  IBM  DB2•  Microsoh  SQL  Server  2005•  Firebird•  ODBC

2.  Instalación  SGBD

Page 111: Desarrollo web ágil con Python y Django

Configurar  un  motor  de  Base  de  Datos:

•  Oficiales:  •  PostgreSQL•  MySQL

•  Oracle•  SQLite

•  Comunidad:  •  Sybase  SQL  Anywhere•  IBM  DB2•  Microsoh  SQL  Server  2005•  Firebird•  ODBC

2.  Instalación  SGBD

Page 112: Desarrollo web ágil con Python y Django

•  Vamos  a  uHlizar  SQLite  por  comodidad

•  Desde  Python  2.5  podemos  uHlizar  sqlite    sin  instalar  nada.

2.  Instalación  SGBD

Page 113: Desarrollo web ágil con Python y Django

•  Vamos  a  uHlizar  SQLite  por  comodidad

•  Desde  Python  2.5  podemos  uHlizar  sqlite    sin  instalar  nada.

2.  Instalación  SGBD

Page 114: Desarrollo web ágil con Python y Django

A:  Paquetes  de  cada  distro

• apt-get install python-django

B:  Official  Release

• http://www.djangoproject.com/download/

• python setup.py install

C:  Github

• git clone https://github.com/django/django.git

3.  Instalación  Django

Page 115: Desarrollo web ágil con Python y Django

All  Right?

Page 116: Desarrollo web ágil con Python y Django

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

Page 117: Desarrollo web ágil con Python y Django
Page 118: Desarrollo web ágil con Python y Django

Bienvenidos  al  mundo  de  Oz

Page 119: Desarrollo web ágil con Python y Django

*  Incluida  la  carpeta  del  proyecto

Ficheros  y  Carpetas¿Es  Django  tán  simple  y  fácil  de  usar?

Page 120: Desarrollo web ágil con Python y Django

*  Incluida  la  carpeta  del  proyecto

Ficheros  y  Carpetas

Ficheros

Carpetas

¿Es  Django  tán  simple  y  fácil  de  usar?

Page 121: Desarrollo web ágil con Python y Django

Rails Symfony

149 117

35 29

*  Incluida  la  carpeta  del  proyecto

Ficheros  y  Carpetas

Ficheros

Carpetas

¿Es  Django  tán  simple  y  fácil  de  usar?

Page 122: Desarrollo web ágil con Python y Django

Rails Symfony

149 117

35 29

*  Incluida  la  carpeta  del  proyecto

Ficheros  y  Carpetas

Ficheros

Carpetas

¿Es  Django  tán  simple  y  fácil  de  usar?

Page 123: Desarrollo web ágil con Python y Django

Rails Symfony

149 117

35 29

*  Incluida  la  carpeta  del  proyecto

Ficheros  y  Carpetas

Django

5

2

Ficheros

Carpetas

¿Es  Django  tán  simple  y  fácil  de  usar?

Page 124: Desarrollo web ágil con Python y Django

Let’s  enjoy

Page 125: Desarrollo web ágil con Python y Django

Crear  nuestro  proyectode  5  ficheros  ;-­‐)

Page 126: Desarrollo web ágil con Python y Django

Crear  nuestro  proyecto

$ django-admin.py startproject dwitter

de  5  ficheros  ;-­‐)

Page 127: Desarrollo web ágil con Python y Django

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  ;-­‐)

Page 128: Desarrollo web ágil con Python y Django

sesngs.py

Page 129: Desarrollo web ágil con Python y Django

Arrancar  nuestro  proyectode  5  ficheros  ;-­‐)

Page 130: Desarrollo web ágil con Python y Django

Arrancar  nuestro  proyectode  5  ficheros  ;-­‐)

$ cd dwitter$ python manage.py runserver

Validating models...0 errors found

Django version 1.4, using settings 'dwitter.settings'Development server is running at http://127.0.0.1:8000/Quit the server with CONTROL-C.

Page 131: Desarrollo web ágil con Python y Django

Arrancar  nuestro  proyectode  5  ficheros  ;-­‐)

$ cd dwitter$ python manage.py runserver

Validating models...0 errors found

Django version 1.4, using settings 'dwitter.settings'Development server is running at http://127.0.0.1:8000/Quit the server with CONTROL-C.

Page 132: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 133: Desarrollo web ágil con Python y Django

MVC  en  Django

Modelo  =  Model Vista  =  Template Controlador  =  URL+View

Page 134: Desarrollo web ágil con Python y Django

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.py

urls.py

views.py

hGp://mysite.com/about/

html ...

¿urlpaGerns?

Page 135: Desarrollo web ágil con Python y Django

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@pResponse

views.py

H@pRequest(),  ...

H@pResponse()

Page 136: Desarrollo web ágil con Python y Django

URLs  y  VistasEjemplo  1:    http://mysite.com/time

from django.conf.urls.defaults import *from mysite.views import hora_actual

urlpatterns = patterns('', url(r'^time/$', hora_actual),)

from django.http import HttpResponsefrom datetime import datetime

def hora_actual(request): now = datetime.now() html = "Son las %s." % now

return HttpResponse(html)

urls.py

views.py

Page 137: Desarrollo web ágil con Python y Django

URLs  y  Vistas

from django.conf.urls.defaults import *from mysite.views import dentro_de

urlpatterns = patterns('', url(r'^time/plus/(\d{1,2})/$', dentro_de),)

from django.http import HttpResponsefrom datetime import datetime, timedelta

def 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.py

views.py

Ejemplo  2:    http://mysite.com/time/plus/2

Page 138: Desarrollo web ágil con Python y Django
Page 139: Desarrollo web ágil con Python y Django

URLs  y  Vistas

from django.conf.urls.defaults import *from mysite.views import dentro_de

urlpatterns = patterns('', url(r'^time/plus/(\d{1,2})/$', dentro_de),)

from django.http import HttpResponsefrom datetime import datetime, timedelta

def 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.py

views.py

Ejemplo  2:    http://mysite.com/time/plus/2

Page 140: Desarrollo web ágil con Python y Django

¡Recuerda!:  MVC

Page 141: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 142: Desarrollo web ágil con Python y Django

Templates• Separan  la  lógica  de  presentación  a  una  capa  independiente.

• Ficheros  independientes  (.html)

• Lenguaje  independiente  (¡para  diseñadores!)

Page 143: Desarrollo web ágil con Python y Django

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."

Page 144: Desarrollo web ágil con Python y Django

Templates

from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetime

PLANTILLA = """<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

Page 145: Desarrollo web ágil con Python y Django

Templates• Segunda  aproximación  al  obje*vo:  open(),  read(),  close()

from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetime

def 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)

Page 146: Desarrollo web ágil con Python y Django

Templates• Segunda  aproximación  al  obje*vo:  open(),  read(),  close()

from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetime

def 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)

Page 147: Desarrollo web ágil con Python y Django

Templates• Segunda  aproximación  al  obje*vo:  open(),  read(),  close()

from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetime

def 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!

Page 148: Desarrollo web ágil con Python y Django

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 datetime

def 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

Page 149: Desarrollo web ágil con Python y Django

Templates• Tercera  aproximación  al  obje*vo:  get_template()

TEMPLATE_DIRS = ( '/home/django/templates',)

senngs.py

from django.http import HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom datetime import datetime

def hora_actual(request): now = datetime.now() t = get_template('hora.html') c = Context({'hora': now}) html = t.render(c) return HttpResponse(html)

Page 150: Desarrollo web ágil con Python y Django

Templates• Tercera  aproximación  al  obje*vo:  get_template()

TEMPLATE_DIRS = ( '/home/django/templates',)

senngs.py

from django.http import HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom datetime import datetime

def 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...

Page 151: Desarrollo web ágil con Python y Django

Templates• Obje*vo  alcanzado:  render()

from django.shortcuts import renderfrom datetime import datetime

def hora_actual(request): now = datetime.now() return render(request, 'hora.html', {'hora': now})

Page 152: Desarrollo web ágil con Python y Django

Templates• Obje*vo  alcanzado:  render()

from django.shortcuts import renderfrom datetime import datetime

def hora_actual(request): now = datetime.now() return render(request, 'hora.html', {'hora': now})

Boring...?

Page 153: Desarrollo web ágil con Python y Django

Templates• Obje*vo  alcanzado:  render()

from django.shortcuts import renderfrom datetime import datetime

def hora_actual(request): now = datetime.now() return render(request, 'hora.html', {'hora': now})

AWESOME!

Page 154: Desarrollo web ágil con Python y Django

Templates:  TipTEMPLATE_DIRS = ( '/home/django/templates',)

senngs.pya)

Page 155: Desarrollo web ágil con Python y Django

Templates:  TipTEMPLATE_DIRS = ( '/home/django/templates',)

senngs.py Reusable  

apps?a)

Page 156: Desarrollo web ágil con Python y Django

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:

Page 157: Desarrollo web ágil con Python y Django

¡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)

Page 159: Desarrollo web ágil con Python y Django

Git

Page 160: Desarrollo web ágil con Python y Django

Git

Quiero  ir  a...

¿Donde  estoy?

Page 161: Desarrollo web ágil con Python y Django

Git

$ git clone https://github.com/enjoydjango/dwitter.git

$ git checkout -t origin/step-01-views

Quiero  ir  a...

$ git branch

¿Donde  estoy?

$ git checkout step-01-views

Page 162: Desarrollo web ágil con Python y Django

Git

Ignorar  todos  los  cambios  *

*  Si  no  habéis  commiteado  nada

Page 163: Desarrollo web ágil con Python y Django

Git

$ git reset --hard HEAD $ git clean -fd

Ignorar  todos  los  cambios  *

*  Si  no  habéis  commiteado  nada

Page 165: Desarrollo web ágil con Python y Django

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

Page 166: Desarrollo web ágil con Python y Django

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

Page 167: Desarrollo web ágil con Python y Django

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.

Page 168: Desarrollo web ágil con Python y Django

Templates:  {{}}<html> <head>Ejemplo templates</head> <body> Hola, {{ username }}. </body></html>

{'username': 'juan'}

<html> <head>Ejemplo templates</head> <body> Hola, juan. </body></html>

Page 169: Desarrollo web ágil con Python y Django

Filters  y  Tags

Page 170: Desarrollo web ágil con Python y Django

Filters  y  Tags

Page 171: Desarrollo web ágil con Python y Django

Filters  y  Tags

{{ varible|filter }}filter

Page 172: Desarrollo web ágil con Python y Django

Filters  y  Tags

{{ varible|filter }}filter

{% tag var1 var2 %}inline  tag

Page 173: Desarrollo web ágil con Python y Django

Filters  y  Tags

{{ varible|filter }}filter

{% tag var1 var2 %}inline  tag

{% tag var1 %} ...{% endtag %}

block  tag

Page 174: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}

Page 175: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}

{% comment %} Bu! {% endcomment %}comment

Page 176: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}

{% comment %} Bu! {% endcomment %}comment

for {% for elemento in lista %} <li>{{ elemento }}<li>{% endfor %}

Page 177: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}

{% comment %} Bu! {% endcomment %}comment

for {% for elemento in lista %} <li>{{ elemento }}<li>{% endfor %}

if {% if username == "Juan" %} Hola Juan, me gustas!{% else %} Hola {{ username }},{% endif %}

== != > < >= <=in and or not

Page 178: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}

Page 179: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}cycle {% for elemento in lista %}

<li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>{% endfor %}

Page 180: Desarrollo web ágil con Python y Django

Templates:  tags  {%  %}cycle {% for elemento in lista %}

<li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>{% endfor %}

include {% include "foo/bar.html" %}

Page 181: Desarrollo web ágil con Python y Django

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 %}

Page 182: Desarrollo web ágil con Python y Django

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 %}

Page 183: Desarrollo web ágil con Python y Django

 

Tarea:  Tagsa) UHlizar  tags  para  que  el  Hmeline  se  muestre  con  el  siguiente  formato:• <username>:  <tweet>  <Hmestamp>• <username>:  <tweet>  <Hmestamp>• ...

Page 184: Desarrollo web ágil con Python y Django

 

Tarea:  Tags  avanzadosa) Hacer  que  el  Hmeline  muestre  el  mensaje  “No  hay  tweets.”  si  el  diccionario  recibido  está  vacío.

Page 185: Desarrollo web ágil con Python y Django

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

Page 186: Desarrollo web ágil con Python y Django

Templates:  Filters

Page 187: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es majo'}

{{ username|length }}length 12

Page 188: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es majo'}

{{ username|length }}length 12

{{ username|cut }}cut Juanesmajo

Page 189: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es majo'}

{{ username|length }}length 12

{{ username|cut }}cut Juanesmajo

{{ username|slugify }}slugify juan-es-majo

Page 190: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es majo'}

{{ username|length }}length 12

{{ username|cut }}cut Juanesmajo

{{ username|slugify }}slugify juan-es-majo

{{ username|wordcount }}wordcount 3

Page 191: Desarrollo web ágil con Python y Django

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

Page 192: Desarrollo web ágil con Python y Django

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

Page 193: Desarrollo web ágil con Python y Django

Templates:  Filters

Page 194: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'}

{{ username|striptags }}striptags

Juan es majo guapo y listo

Page 195: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'}

{{ username|striptags }}striptags

Juan es majo guapo y listo

{{ username|truncatewords_html:4 }}truncatewords_html

Juan es <b>majo guapo</b> ...

Page 196: Desarrollo web ágil con Python y Django

Templates:  Filters{'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'}

{{ username|striptags }}striptags

Juan es majo guapo y listo

{{ username|truncatewords_html:4 }}truncatewords_html

Juan es <b>majo guapo</b> ...

{{ username|removetags:”em a br” }}removetags

Juan es <b>majo guapo y listo</b>

Page 197: Desarrollo web ágil con Python y Django

Templates:  Filters

Page 198: Desarrollo web ágil con Python y Django

Templates:  Filters{'url': 'Visitad http://www.djangoproject.com'}

{{ url|urlize }}urlize

Visitad <a href=”http://www.djangoproject.com”> http://www.djangoproject.com </a>

Page 199: Desarrollo web ágil con Python y Django

Templates:  Filters{'url': 'Visitad http://www.djangoproject.com'}

{{ url|urlize }}urlize

Visitad <a href=”http://www.djangoproject.com”> http://www.djangoproject.com </a>

{{ url|urlizetrunc:16 }}urlizetrunc

Visitad <a href=”http://www.djangoproject.com”> http://www.djang...</a>

Page 200: Desarrollo web ágil con Python y Django

Templates:  Filters{'lista': ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]}

Page 201: Desarrollo web ágil con Python y Django

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>

Page 202: Desarrollo web ágil con Python y Django

Templates:  Filters

Page 203: Desarrollo web ágil con Python y Django

Templates:  Filters{'value': 123456789}

{{ value|add:”1” }}add 123456790

Page 204: Desarrollo web ágil con Python y Django

Templates:  Filters{'value': 123456789}

{{ value|add:”1” }}add 123456790

{{ value|filesizeformat }}filesizeformat 117.7MB

Page 205: Desarrollo web ágil con Python y Django

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

Page 206: Desarrollo web ágil con Python y Django

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

Page 207: Desarrollo web ágil con Python y Django

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

Page 208: Desarrollo web ágil con Python y Django

Tarea:  Filtersa) Añadir  a  cada  tweet  del  Hmeline  el  Hempo  transcurrido:• <username>:  <tweet>

<n>  seconds  ago• <username>:  <tweet>

<n>  minutes  ago• ...

Page 209: Desarrollo web ágil con Python y Django

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”  

Page 210: Desarrollo web ágil con Python y Django

Tarea:  Filtersc) Conseguir  que  todas  las  urls  que  aparezcan  en  los  tweets  se  conviertan  en  enlaces  <a  href=...  />  de  HTML.

Page 211: Desarrollo web ágil con Python y Django

Herencia  de  Templates

base.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 %}

Page 212: Desarrollo web ágil con Python y Django

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

Page 213: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 214: Desarrollo web ágil con Python y Django

Modelos

Page 215: Desarrollo web ágil con Python y Django

¿SQL?

Page 216: Desarrollo web ágil con Python y Django

Ejemplo  SQL

def 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})

Page 217: Desarrollo web ágil con Python y Django

Ejemplo  SQL

def 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})

12

34

5

6

Page 218: Desarrollo web ágil con Python y Django

12  lineas  de  Python...  ¬_¬

Page 219: Desarrollo web ágil con Python y Django

ORM  (Object-­‐RelaHonal  mapping)

Page 220: Desarrollo web ágil con Python y Django

ORM  (Object-­‐RelaHonal  mapping)

Page 221: Desarrollo web ágil con Python y Django

Ejemplo  ORM

def book_list(request):

names = Books.objects.all().order_by('name')

return render(request, 'book_list.html', {'names':names})

Page 222: Desarrollo web ágil con Python y Django

Ejemplo  ORM

def book_list(request):

names = Books.objects.all().order_by('name')

return render(request, 'book_list.html', {'names':names})

1 2

Page 223: Desarrollo web ágil con Python y Django

Fucking  Ninjas!

Page 224: Desarrollo web ágil con Python y Django

Modelofrom django.db import models

class 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)  

Page 225: Desarrollo web ágil con Python y Django

Modelofrom django.db import models

class Books(models.Model):

name = models.CharField(blank=True, max_length=100)

created = models.DateTimeField(blank=False)

available = models.BooleanField(default=True)

2

1

3

4

5

6

•  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)  

Page 226: Desarrollo web ágil con Python y Django

Fucking  Awesome  Ninjas!

Page 227: Desarrollo web ágil con Python y Django

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

Page 228: Desarrollo web ágil con Python y Django

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

Page 229: Desarrollo web ágil con Python y Django

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

Page 230: Desarrollo web ágil con Python y Django

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

Page 231: Desarrollo web ágil con Python y Django

¿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;

Page 232: Desarrollo web ágil con Python y Django

¿Es  magia?  No.$ python manage.py sqlall website

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;

Page 233: Desarrollo web ágil con Python y Django

¿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

Page 234: Desarrollo web ágil con Python y Django

Configurar  seyngs.py

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.',

'NAME': '',

'USER': '',

'PASSWORD': '',

'HOST': '',

'PORT': '',

}

}

'postgresql_psycopg2',

'postgresql', 'mysql',

'sqlite3' or 'oracle'.

Page 235: Desarrollo web ágil con Python y Django

Configurar  seyngs.py

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.',

'NAME': '',

'USER': '',

'PASSWORD': '',

'HOST': '',

'PORT': '',

}

}

1

2

3

'postgresql_psycopg2',

'postgresql', 'mysql',

'sqlite3' or 'oracle'.

Page 236: Desarrollo web ágil con Python y Django

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

Page 237: Desarrollo web ágil con Python y Django

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

Page 238: Desarrollo web ágil con Python y Django

Nuestro  primer  modelo

a)Crear  modelo  Tweetb)Configurar  sesngs.pyc) Ver  el  SQL  generado  con  sqlall

Page 239: Desarrollo web ágil con Python y Django

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_tweet

You just installed Django's auth system, which means you don't have any superusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use 'neo'): admin E-mail address: [email protected]: Password (again): Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet model

Page 240: Desarrollo web ágil con Python y Django

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_tweet

You just installed Django's auth system, which means you don't have any superusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use 'neo'): admin E-mail address: [email protected]: Password (again): Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet model

django.contrib.auth

Page 241: Desarrollo web ágil con Python y Django

¿Cuantos  sistemas  de  AutenHcación  habéis  programado?

Page 242: Desarrollo web ágil con Python y Django

¿Alguno  era  mejor  que  el  anterior?  ;-­‐)

Page 243: Desarrollo web ágil con Python y Django

contrib.auth  puede  ser  el  úlHmo  :D

Page 244: Desarrollo web ágil con Python y Django

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_tweet

You just installed Django's auth system, which means you don't have any superusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use 'neo'): admin E-mail address: [email protected]: Password (again): Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet model

website.tweet

Page 245: Desarrollo web ágil con Python y Django

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_tweet

You just installed Django's auth system, which means you don't have any superusers defined.Would you like to create one now? (yes/no): yesUsername (Leave blank to use 'neo'): admin E-mail address: [email protected]: Password (again): Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling index for website.Tweet model

django.contrib.auth

Page 246: Desarrollo web ágil con Python y Django

BD  Lista  para  usarse

Page 247: Desarrollo web ágil con Python y Django

BD  Lista  para  usarse

Page 248: Desarrollo web ágil con Python y Django

Nuestro  primer  modelo

a)Hacer  syncdb

Page 249: Desarrollo web ágil con Python y Django
Page 250: Desarrollo web ágil con Python y Django

Previo:  Clases  del  ORM

ts = Publisher.objects.all()

Model

Manager

QuerySet

Page 251: Desarrollo web ágil con Python y Django

INSERT

Page 252: Desarrollo web ágil con Python y Django

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()

Page 253: Desarrollo web ágil con Python y Django

INSERT

>>> p = Publisher.objects.create(... name='O'Reilly',... 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)

Page 254: Desarrollo web ágil con Python y Django

UPDATE

Page 255: Desarrollo web ágil con Python y Django

UPDATE

>>> ...>>> p.id52>>> p.name = 'Apress Publishing'>>> p.save()

o.save()

1

Page 256: Desarrollo web ágil con Python y Django

UPDATE

>>> Publisher.objects.all().update(country='USA')2

>>> ...>>> p.id52>>> p.name = 'Apress Publishing'>>> p.save()

o.save()

queryset.update(...)

1

n

Page 257: Desarrollo web ágil con Python y Django

DELETE

Page 258: Desarrollo web ágil con Python y Django

DELETE

>>> ...>>> p.id52>>> p.delete()

o.delete()

1

Page 259: Desarrollo web ágil con Python y Django

DELETE

>>> ps = Publisher.objects.all()>>> ps.delete()

>>> ...>>> p.id52>>> p.delete()

o.delete()

queryset.delete()

1

n

Page 260: Desarrollo web ágil con Python y Django

SELECT  de  1  resultado

Page 261: Desarrollo web ágil con Python y Django

SELECT  de  1  resultado

>>> Publisher.objects.get(name="Apress")<Publisher: Apress>

.get(...)

Page 262: Desarrollo web ágil con Python y Django

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.

Page 263: Desarrollo web ágil con Python y Django

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.

Page 264: Desarrollo web ágil con Python y Django

SELECT  de  N  resultados

Page 265: Desarrollo web ágil con Python y Django

SELECT  de  N  resultados

>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: O'Reilly>]

.all()

Page 266: Desarrollo web ágil con Python y Django

SELECT  de  N  resultados

>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: O'Reilly>]

.all()

>>> Publisher.objects.filter( country="U.S.A.", state_province="CA")[<Publisher: Apress>]

.filter(...)

Page 267: Desarrollo web ágil con Python y Django

SELECT  de  N  resultados

>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: O'Reilly>]

.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: O'Reilly>]

.exclude(...)

Page 268: Desarrollo web ágil con Python y Django

SELECT  de  N  resultados

>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: O'Reilly>]

.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: O'Reilly>]

.exclude(...)

¡Devuelven  

QuerySets,  no

 

listas!

Page 269: Desarrollo web ágil con Python y Django

get(),  filter()  y  exclude()

Page 270: Desarrollo web ágil con Python y Django

get(),  filter()  y  exclude()Modelo.objects.filter(campo1="valor1", campo2="valor2")

Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=)

Page 271: Desarrollo web ágil con Python y Django

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|F

campo__day=31

campo__gt=0

campo__gte=0

campo__lt=0

campo__lte=0

campo__in=[ ,]

campo__month=12

campo__startswith=''

campo__istartswith=''

campo__endswith=''

campo__iendswith=''

campo__range=( ,)

campo__year=2010

Page 272: Desarrollo web ágil con Python y Django

ORDER  BY

Page 273: Desarrollo web ágil con Python y Django

ORDER  BY

>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: O'Reilly>]

.order_by(...)

Page 274: Desarrollo web ágil con Python y Django

ORDER  BY

>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: O'Reilly>]

.order_by(...)

>>> Publisher.objects.order_by("-name")[<Publisher: O'Reilly>, <Publisher: Apress>]

Page 275: Desarrollo web ágil con Python y Django

ORDER  BY

>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: O'Reilly>]

.order_by(...)

>>> Publisher.objects.order_by("-name")[<Publisher: O'Reilly>, <Publisher: Apress>]

>>> Publisher.objects.order_by("-name", "country")[<Publisher: O'Reilly>, <Publisher: Apress>]

MúlHples  campos:

Page 276: Desarrollo web ágil con Python y Django

ORDER  BY

>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: O'Reilly>]

.order_by(...)

>>> Publisher.objects.order_by("-name")[<Publisher: O'Reilly>, <Publisher: Apress>]

>>> Publisher.objects.order_by("-name", "country")[<Publisher: O'Reilly>, <Publisher: Apress>]

MúlHples  campos:

¡También  

devuelve  

QuerySets!

Page 277: Desarrollo web ágil con Python y Django

Slicing

Page 278: Desarrollo web ágil con Python y Django

Slicing

>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>

[n:m]

>>> Publisher.objects.order_by("name")[:2][<Publisher: Apress>, <Publisher: O'Reilly>]

>>> Publisher.objects.order_by("name")[1:2][<Publisher: O'Reilly>]

Page 279: Desarrollo web ágil con Python y Django

Slicing

>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>

[n:m]

>>> Publisher.objects.order_by("name")[:2][<Publisher: Apress>, <Publisher: O'Reilly>]

>>> Publisher.objects.order_by("name")[1:2][<Publisher: O'Reilly>]

LIMIT

Page 280: Desarrollo web ágil con Python y Django

Slicing

>>> Publisher.objects.order_by("name")[0]<Publisher: Apress>

[n:m]

>>> Publisher.objects.order_by("name")[:2][<Publisher: Apress>, <Publisher: O'Reilly>]

>>> Publisher.objects.order_by("name")[1:2][<Publisher: O'Reilly>]

LIMIT

OFFSET

Page 281: Desarrollo web ágil con Python y Django

Related  Objects

Page 282: Desarrollo web ágil con Python y Django

Related  ObjectsOneToOneField

class Coche(models.Model): motor = OneToOneField(Motor)

class Motor(models.Model): ...

1

1

Page 283: Desarrollo web ágil con Python y Django

Related  ObjectsOneToOneField

class 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  nosotros

1

1

Page 284: Desarrollo web ágil con Python y Django

Related  ObjectsOneToOneField

class 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  Django

1

1

Page 285: Desarrollo web ágil con Python y Django

Related  Objects

Page 286: Desarrollo web ágil con Python y Django

Related  ObjectsForeignKeyField

class Blog(models.Model): ...

class Post(models.Model): blog = ForeignKeyField(Blog)

1

n

Page 287: Desarrollo web ágil con Python y Django

Related  ObjectsForeignKeyField

class 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  Django

1

n

Page 288: Desarrollo web ágil con Python y Django

Related  Objects

Page 289: Desarrollo web ágil con Python y Django

Related  ObjectsManyToManyField

class Post(models.Model): tags = ManyToManyField(Tag)

class Tag(models.Model): ...

n

m

Page 290: Desarrollo web ágil con Python y Django

Related  ObjectsManyToManyField

class 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  Django

n

m

Page 291: Desarrollo web ágil con Python y Django

Related  Objects

Page 292: Desarrollo web ágil con Python y Django

Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inverso

class Blog(models.Model): ...

class Post(models.Model): blog = ForeignKeyField(Blog, related_name='posts')

1

n

Page 293: Desarrollo web ágil con Python y Django

Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inverso

class 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  Django

1

n

Page 294: Desarrollo web ágil con Python y Django

Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inverso

class 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  Django

1

n

Cuando  haya  2  relaciones  entre  2  modelos,  será  obligatorio

Page 295: Desarrollo web ágil con Python y Django

Y  la  guinda  final:  ¡Todo  es  LAZY!

Page 296: Desarrollo web ágil con Python y Django

Laziness

Page 297: Desarrollo web ágil con Python y Django

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'):

Page 298: Desarrollo web ágil con Python y Django

Nota:  __unicode__()

Page 299: Desarrollo web ágil con Python y Django

Nota:  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]

Page 300: Desarrollo web ágil con Python y Django

Nota:  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]

Page 301: Desarrollo web ágil con Python y Django

Nota:  __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]

Page 302: Desarrollo web ágil con Python y Django

Nota:  __unicode__()

class Publisher(models.Model): ... def __unicode__(self): return self.name

>>> Publisher.objects.all()[<Publisher: Publisher object>]

Page 303: Desarrollo web ágil con Python y Django

Nota:  __unicode__()

class Publisher(models.Model): ... def __unicode__(self): return self.name

>>> Publisher.objects.all()[<Publisher: Publisher object>]

>>> Publisher.objects.all()[<Publisher: Apress>]

Page 304: Desarrollo web ágil con Python y Django

Usando  el  ORM

a) Insertar  varios  Tweets  desde  la  shell.b)Modificar  views.timeline  para  que  uHlice  los  Tweets  reales  de  la  BD.

Page 305: Desarrollo web ágil con Python y Django

Usando  el  ORM

c) 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

Page 306: Desarrollo web ágil con Python y Django

Profiles

Page 307: Desarrollo web ágil con Python y Django

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.

Page 308: Desarrollo web ágil con Python y Django

Profile

models.py

Page 309: Desarrollo web ágil con Python y Django

Profile

class 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.

Page 310: Desarrollo web ágil con Python y Django

Profile

•Donde  tengamos  el  User  tendremos  el  Profile.•Donde  tengamos  el  Profile,  tendremos  el  User.

Page 311: Desarrollo web ágil con Python y Django

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.

Page 312: Desarrollo web ágil con Python y Django

1  User  =  1  Profile  ¿Cuándo  se  crea  un  User?

Page 313: Desarrollo web ágil con Python y Django

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/

Page 314: Desarrollo web ágil con Python y Django

Signals

Page 315: Desarrollo web ágil con Python y Django

Signals

def 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)

1

2

3

Puede  estar  en  cualquier  app  de  nuestro  proyecto.

Se  recomienda  models.py

Page 316: Desarrollo web ágil con Python y Django

Users  en  dwiier

a)Crear  el  modelo  Profileb)Crear  signal  para  agregar  un  objeto  Profile  a  cada  objeto  User  creado.

c) Eliminar  BD.d)Hacer  syncdb

Page 317: Desarrollo web ágil con Python y Django

Followers

Page 318: Desarrollo web ágil con Python y Django

Profilemodels.py

Page 319: Desarrollo web ágil con Python y Django

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

Page 320: Desarrollo web ágil con Python y Django

Users  en  dwiier

a)Añadir  ManyToMany  para  los  followers.b)Eliminar  BD.c) Hacer  syncdb

Page 321: Desarrollo web ágil con Python y Django

1,2,3  Borrar  la  BD....  1,2,3...  Borrar  la  BD

Page 322: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 323: Desarrollo web ágil con Python y Django

CRUD:  Create,  Retrieve,  Update  &  Delete

Page 324: Desarrollo web ágil con Python y Django

django.contrib.admin

1

2

3

Page 325: Desarrollo web ágil con Python y Django

django.contrib.admin

1

2

3

Page 326: Desarrollo web ágil con Python y Django

django.contrib.admin

1

Page 327: Desarrollo web ágil con Python y Django

Django  admin:  Instalación

from 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)),

...

)

1

2

urls.py

Page 328: Desarrollo web ágil con Python y Django

Django  admin:  Instalación

from 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)),

...

)

1

2

urls.py

Page 329: Desarrollo web ágil con Python y Django

Django  admin:  Instalación

INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', ...)

senngs.py

Page 330: Desarrollo web ágil con Python y Django

Django  admin:  Instalación

INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', ...)

senngs.py

1

Page 331: Desarrollo web ágil con Python y Django

Actualizando  la  BD

Page 332: Desarrollo web ágil con Python y Django

Actualizando  la  BD

$ python manage.py syncdb

Creating table django_admin_log

Installing index for admin.LogEntry model

Admin  lista  para  usar

Page 333: Desarrollo web ágil con Python y Django

¿Y  nuestra  app?

?

Page 334: Desarrollo web ágil con Python y Django

¿Y  nuestra  app?

Page 335: Desarrollo web ágil con Python y Django

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 admin

from website.models import Tweet

class TweetAdmin(admin.ModelAdmin):

list_display = ('id','user','message','timestamp')

admin.site.register(Tweet, TweetAdmin)

Page 336: Desarrollo web ágil con Python y Django

Instalar  Admin

a)Configurar  urls.pyb)Configurar  sesngs.pyc) Hacer  syncdb

Page 337: Desarrollo web ágil con Python y Django

Instalar  Admin

d)Comprobar  que  no  están  Tweet  y  Profilee)Añadir  admin.pyf) Probar  Administración.

Page 338: Desarrollo web ágil con Python y Django

Fixtures

Page 339: Desarrollo web ágil con Python y Django

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:

Page 340: Desarrollo web ágil con Python y Django

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 ...>

Page 341: Desarrollo web ágil con Python y Django

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.

Page 342: Desarrollo web ágil con Python y Django

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

Page 343: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 344: Desarrollo web ágil con Python y Django

Formularios

Page 345: Desarrollo web ágil con Python y Django

Clases  involucradas

Page 346: Desarrollo web ágil con Python y Django

Clases  involucradasWidget Componente  visual  equivalente  a  HTML

TextInput

CheckboxInput

<input type='text'...>

<input type='checkbox'...>

Page 347: Desarrollo web ágil con Python y Django

Clases  involucradasWidget Componente  visual  equivalente  a  HTML

TextInput

CheckboxInput

<input type='text'...>

<input type='checkbox'...>

Field Lógica  de  un  campo,  asociado  a  un  WidgetEmailField

IPAddressFieldwidget, initial, error, ...

Page 348: Desarrollo web ágil con Python y Django

Clases  involucradasWidget Componente  visual  equivalente  a  HTML

TextInput

CheckboxInput

<input type='text'...>

<input type='checkbox'...>

Field Lógica  de  un  campo,  asociado  a  un  WidgetEmailField

IPAddressFieldwidget, initial, error, ...

Form Conjunto  de  Fields  de  un  formularioContactForm [nombre, email, telefono, mensaje, ...]

Page 349: Desarrollo web ágil con Python y Django

Fields

Page 350: Desarrollo web ágil con Python y Django

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

Page 351: Desarrollo web ágil con Python y Django

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

Page 352: Desarrollo web ágil con Python y Django

Creación  de  un  Form

from django import forms

class 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

Page 353: Desarrollo web ágil con Python y Django

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

Page 354: Desarrollo web ágil con Python y Django

Creación  de  un  Form

from django.shortcuts import render

from mysite.contact.forms import ContactForm

def contact(request):

if request.method == 'POST':

form = ContactForm(request.POST)

if form.is_valid():

cd = form.cleaned_data

send_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

Page 355: Desarrollo web ágil con Python y Django

Creación  de  un  Form

from django.shortcuts import render

from mysite.contact.forms import ContactForm

def contact(request):

if request.method == 'POST':

form = ContactForm(request.POST)

if form.is_valid():

cd = form.cleaned_data

send_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

Paiern

Page 356: Desarrollo web ágil con Python y Django

Creación  de  un  Form

from django.shortcuts import render

from mysite.contact.forms import ContactForm

def contact(request):

if request.method == 'POST':

form = ContactForm(request.POST)

if form.is_valid():

cd = form.cleaned_data

send_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

Paiern

Page 357: Desarrollo web ágil con Python y Django

Creación  de  un  Form

from django.shortcuts import render

from mysite.contact.forms import ContactForm

def contact(request):

if request.method == 'POST':

form = ContactForm(request.POST)

if form.is_valid():

cd = form.cleaned_data

send_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

Paiern

Page 358: Desarrollo web ágil con Python y Django

Validación  propia

from django import forms

class 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 message

Podemos  programar  validación  extra  asociada  a  cada  Field  del  formulario  escribiendo  un  método  clean_<fieldname>:

Page 359: Desarrollo web ágil con Python y Django

Validación  propia

from django import forms

class 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 message

Podemos  programar  validación  extra  asociada  a  cada  Field  del  formulario  escribiendo  un  método  clean_<fieldname>:

Page 360: Desarrollo web ágil con Python y Django

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:

Page 361: Desarrollo web ágil con Python y Django

Forms  a  parHr  de  Models:  El  COLMO  del  DRY

Page 362: Desarrollo web ágil con Python y Django

Forms  a  par/r  de  Modelsfrom django.db import models

class Author(models.Model):

name = models.CharField(max_length=100)

birth_date = models.DateField(blank=True, null=True)

country = models.ModelChoiceField(Country)

...

from django import forms

from books.models import Author

class AuthorForm(forms.ModelForm):

class Meta:

model = Author

exclude = ('country',)

models.py

forms.py

Page 363: Desarrollo web ágil con Python y Django

Primer  Form  en  dwiier

a)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).

Page 364: Desarrollo web ágil con Python y Django

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

Page 365: Desarrollo web ágil con Python y Django

Índice1.Python

a. Introducciónb.Tipos  de  datosc. Operadoresd.Usos  frecuentese. Estructurasf. Sentenciasg. Ejercicio

2.Djangoa. Introducciónb.URLs  y  Vistasc. Templatesd.Modeloe. Administraciónf. Formulariosg. Magia  avanzada

Proyecto

Page 366: Desarrollo web ágil con Python y Django

Magia  avanzada

Page 367: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 368: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 369: Desarrollo web ágil con Python y Django

Views  avanzadas

from 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

Page 370: Desarrollo web ágil con Python y Django

Views  avanzadas

from 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!

Page 371: Desarrollo web ágil con Python y Django

Views  avanzadasEn  ficheros  urls.py  que  gesHonen  varias  apps...

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'),)

urlpatterns += patterns('weblog.views', url(r'^tag/(\w+)/$', 'tag'),)

Page 372: Desarrollo web ágil con Python y Django

Views  avanzadasEn  ficheros  urls.py  que  gesHonen  varias  apps...

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'),)

urlpatterns += patterns('weblog.views', url(r'^tag/(\w+)/$', 'tag'),)

Page 373: Desarrollo web ágil con Python y Django

Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

Page 374: Desarrollo web ágil con Python y Django

Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

Page 375: Desarrollo web ágil con Python y Django

Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

Page 376: Desarrollo web ágil con Python y Django

Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

Page 377: Desarrollo web ágil con Python y Django
Page 378: Desarrollo web ágil con Python y Django

NUNCAINFRAVALORÉIS

EL  PODERDE  UN  PONYROSA

Page 379: Desarrollo web ágil con Python y Django

Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

Page 380: Desarrollo web ágil con Python y Django

Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

Page 381: Desarrollo web ágil con Python y Django

Views  avanzadasGeneric  Views

Vistas  con  funcionalidad  genérica  parametrizable  mediante  un  diccionario  de  Extra  Op/ons

from django.conf.urls.defaults import *from mysite import views

urlpatterns = patterns('', url(r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}), url(r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),)

Las  tuplas  de  pa@erns()  pueden  tener  3  elementos

Page 382: Desarrollo web ágil con Python y Django

Views  avanzadas

Renderiza  directamente  la  template  indicada

from django.conf.urls.defaults import *from django.views.generic.simple import direct_to_template

urlpatterns = patterns('', url(r'^about/$', direct_to_template, {'template': 'about.html'}))

from django.views.generic.simple import direct_to_template

Es  la  Generic  View  más  simple  y  más  uHlizada

Page 383: Desarrollo web ágil con Python y Django

Extra  OpHons  en  urls.py

a)Definir  dos  nuevas  URLs  en  urls.py  que  se  sirvan  de  las  vistas  de  django.contrib.auth  para  implementar  login  y  logout:‣ URL:    login/‣ View:    auth.views.login‣ Template:    login.html    (Descargar)

‣ URL:    logout/‣ View:    auth.views.logout‣ Template:    [redirect a /]

 h@p://bit.ly/login-­‐template

Page 384: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 385: Desarrollo web ágil con Python y Django

Context  Processors

!

!

!

!

Page 386: Desarrollo web ágil con Python y Django

Context  Processors¿Context  Processors?  Son  funciones.

• Reciben  un  HGpRequest()  como  único  parámetro.

• Devuelven  un  diccionario  para  ser  usado  como  Context().

Page 387: Desarrollo web ágil con Python y Django

Context  Processors¿Context  Processors?  Son  funciones.

def ip_address_processor(request): return {'ip_address': request.META['REMOTE_ADDR']}

• Reciben  un  HGpRequest()  como  único  parámetro.

• Devuelven  un  diccionario  para  ser  usado  como  Context().

Page 388: Desarrollo web ágil con Python y Django

Context  Processors¿Context  Processors?  Son  funciones.

def ip_address_processor(request): return {'ip_address': request.META['REMOTE_ADDR']}

• Reciben  un  HGpRequest()  como  único  parámetro.

• Devuelven  un  diccionario  para  ser  usado  como  Context().

TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.contrib.messages.context_processors.messages", "website.context_processors.ip_address_processor",)

Page 389: Desarrollo web ágil con Python y Django

Context  Processors

En  lugar  de  encapsular  sólo  el  contexto  de  esta  vista  con  Context,  la  función  render()  instancia  RequestContext,  que  alimenta  nuestro  diccionario  con  todos  los  diccionarios  

devueltos  por  los  Context  Processors  que  tengamos  habilitados.

def view(request): ... return render(request, '...html', {'...': ...})

def render(request, template, context): t = get_template(template) c = RequestContext(request, context) html = t.render(c) return HttpResponse(html)

Page 390: Desarrollo web ágil con Python y Django

ContextProcessors  en  dwiier

c) Cuando  el  usuario  esté  logueado,  mostrar  Bienvenido,  <username>  y  un  link  para  desloguearse.

d)Cuando  no  esté  logueado,  mostrar  un  link  a  /login.

e)Tip:  user.is_authenHcated()

Page 391: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 392: Desarrollo web ágil con Python y Django

Template  LibraryNos  permite  extender  el  sistema  de  templates  

de  Django  con  Filters  y  Tags  propios

Page 393: Desarrollo web ágil con Python y Django

Template  LibraryNos  permite  extender  el  sistema  de  templates  

de  Django  con  Filters  y  Tags  propios

Uso

{% load milibreria %}

...

{{ variable|mifiltro:"param" }}

...

{% mitag param1 param2 %}

Page 394: Desarrollo web ágil con Python y Django

Template  LibraryNos  permite  extender  el  sistema  de  templates  

de  Django  con  Filters  y  Tags  propios

Uso

{% load milibreria %}

...

{{ variable|mifiltro:"param" }}

...

{% mitag param1 param2 %}

Creación

Page 395: Desarrollo web ágil con Python y Django

Custom  FiltersUn  Filter  es  una  función  Python  que:

• Recibe  1  o  2  argumentos:  (value  [,  arg]).

• Siempre  devuelve  algo:  el  resultado,  value  o  "".

• Falla  silenciosamente:  no  lanza  excepciones.

Page 396: Desarrollo web ágil con Python y Django

Custom  FiltersUn  Filter  es  una  función  Python  que:

• Recibe  1  o  2  argumentos:  (value  [,  arg]).

• Siempre  devuelve  algo:  el  resultado,  value  o  "".

• Falla  silenciosamente:  no  lanza  excepciones.

from django import template

register = template.Library()

def cut(value, arg=' '): return value.replace(arg, '') register.filter('cut', cut)

Ejemplo

Page 397: Desarrollo web ágil con Python y Django

Custom  FiltersUn  Filter  es  una  función  Python  que:

• Recibe  1  o  2  argumentos:  (value  [,  arg]).

• Siempre  devuelve  algo:  el  resultado,  value  o  "".

• Falla  silenciosamente:  no  lanza  excepciones.

from django import template

register = template.Library()

@register.filter(name='cut')def cut(value, arg=' '): return value.replace(arg, '')

Page 398: Desarrollo web ágil con Python y Django

Python  

2.4  se  hizo  

sexy

Custom  FiltersUn  Filter  es  una  función  Python  que:

• Recibe  1  o  2  argumentos:  (value  [,  arg]).

• Siempre  devuelve  algo:  el  resultado,  value  o  "".

• Falla  silenciosamente:  no  lanza  excepciones.

from django import template

register = template.Library()

@register.filter(name='cut')def cut(value, arg=' '): return value.replace(arg, '')

Page 399: Desarrollo web ágil con Python y Django

Nuestro  propio  Filter  en  dwiier

a)Crear  un  Filter  llamado  |mention  que  al  detectar  un  “@usuario”  convierta  ese  texto  en  un  enlace  al  perfil  de  dwiier  de  ese  usuario.

Page 400: Desarrollo web ágil con Python y Django

Custom  TagsEl  método  genérico  para  crear  Tags  es  complejo.

Vamos  a  ver  cómo  crear  los  2  Hpos  de  Tags  más  sencillos:

SimpleTags InclusionTags

• Son  inline

• Reciben  1  argumento

• Devuelven  un  string

• Son  inline

• Reciben  n  argumentos

• Devuelven  un  diccionario

• Insertan  su  propio  fragmento  de  template

Page 401: Desarrollo web ágil con Python y Django

SimpleTagsEjemplo:  Devolver  la  hora  actual  formateada.

{% current_time "%Y-%m-%d %I:%M %p" %}

Page 402: Desarrollo web ágil con Python y Django

SimpleTagsEjemplo:  Devolver  la  hora  actual  formateada.

{% current_time "%Y-%m-%d %I:%M %p" %}

from django import template

register = template.Library()

@register.simple_tagdef current_time(format): try: return datetime.datetime.now().strftime(str(format)) except UnicodeEncodeError: return ''

Page 403: Desarrollo web ágil con Python y Django

InclusionTagsEjemplo:  Mostar  anuncios  si  el  usuario  no  es  premium.

{% show_adverts user %}

{% for advert in adverts %} <img src='{{ advert.image }}' />{% endfor %}

adverts.html

milibreria.py

Page 404: Desarrollo web ágil con Python y Django

InclusionTagsEjemplo:  Mostar  anuncios  si  el  usuario  no  es  premium.

@register.inclusion_tag('website/adverts.html')def show_adverts(user): adverts = [] if not user.profile.is_premium: adverts = Advert.objects.order_by('?').limit(5) return {'adverts': adverts}

{% show_adverts user %}

{% for advert in adverts %} <img src='{{ advert.image }}' />{% endfor %}

adverts.html

milibreria.py

Page 405: Desarrollo web ágil con Python y Django

Nuestro  propio  TemplateTag  en  dwiier

a)Crear  un  Tag  llamado  toggle_follow  que  permita  pintar  un  enlace  de  ‘follow’  o  ‘unfollow’  junto  a  cada  usuario  dwiier  que  aparece  listado  en  users_page.html

Page 406: Desarrollo web ágil con Python y Django

Ejercicios  para  subir  nota

c) Implementar  “retweet”:  un  botón  junto  a  cada  tweet  del  Hmeline  que  publique  el  mismo  tweet  en  tu  nombre  precedido  por  “RT  “.

b)Implementar  “borrar  tweet”:  un  botón  junto  a  cada  tweet  propio  que  lo  elimine.

a) Implementar  “página  de  menHons”:  un  Hmeline  que  sólo  muestre  los  tweets  que  te  mencionen  a  H  (Hp:  message__icontains=).

Page 407: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 408: Desarrollo web ágil con Python y Django

MiddlewareNos  permite  escribir  funcionalidad  reu*lizable  que  se  inserta  en  el  flujo  de  ejecución  de  Django

Page 409: Desarrollo web ágil con Python y Django

Middlewareclass MyMiddleware(object):

def process_request(self, request): """Se ejecuta antes de que Django decida a qué View llamar. -> HttpRequest(): Se corta el flujo de middleware. -> None: El flujo sigue con el siguiente middleware.""" # ... def process_view(self, request, view_func, view_args, view_kwargs): """Se ejecuta antes de que se llame a la View. -> HttpRequest(): Se corta el flujo de middleware. -> None: El flujo sigue con el siguiente middleware.""" # ...

def process_response(self, request, response): """Se ejecuta después de que la View devuelva una response. -> HttpResponse()""" # ...

def process_exception(self, request, exception): """Se ejecuta cuando una View lanza una excepción. -> HttpResponse(). -> None: La excepción se propaga hasta el cliente.""" # ...

Page 410: Desarrollo web ágil con Python y Django

MiddlewareTenemos  que  incluir  nuestro  middleware  en  el  lugar  que  nos  convenga,  teniendo  en  cuenta  el  orden  de  

ejecución  en  la  Request  y  en  la  Response:

MIDDLEWARE_CLASSES = (

'django.middleware.common.CommonMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

)

Page 411: Desarrollo web ágil con Python y Django

Middleware1. Sistema  de  BETA

1. Nos  aseguramos  de  controlar  todas  páginas.

2. Si  el  usuario  Hene  una  IP  o  un  User  o...2. Si@o  en  Mantenimiento

1. Todo  el  Site  muestra  un  splash  excepto...

3. Cache  Middleware1. Si  la  vista  cumple  un  patrón  (User  no  logeado,...)  

cacheamos  la  página.

4.  etc...

Page 412: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 413: Desarrollo web ágil con Python y Django

Ofrece  integración  con  la  librería  GNU  ge@ext  de  i18n

1. Un  fichero  .pot  conHene  todos  los  strings  usados

contabilidad.pot

2. En  cada  fichero  .po  se  guarda  una  traducción

es_ES.pot      es_AR.pot      en_GB.pot

3. Cada  .po  se  compila  y  genera  un  .mo  binario

es_ES.mo      es_AR.mo      en_GB.mo

Internacionalización

Page 414: Desarrollo web ágil con Python y Django

Internacionalización• ¿Cómo  indicar  qué  strings  deben  ser  traducidos?

• GesHón  cómoda  de  singulares  y  plurales

Page 415: Desarrollo web ágil con Python y Django

Internacionalización

from django.utils.translation import ugettext as _

print _("Cadena de texto")

• ¿Cómo  indicar  qué  strings  deben  ser  traducidos?

• GesHón  cómoda  de  singulares  y  plurales

Page 416: Desarrollo web ágil con Python y Django

Internacionalización

from django.utils.translation import ugettext as _

print _("Cadena de texto")

• ¿Cómo  indicar  qué  strings  deben  ser  traducidos?

from django.utils.translation import ungettext

frase = ungettext("Hay %(total)d resultado", "Hay %(total)d resultados", total) % { 'total': total }

• GesHón  cómoda  de  singulares  y  plurales

Page 417: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 418: Desarrollo web ágil con Python y Django

caching

•Si  queremos  escalar  nuestro  proyecto  rápidamente....  Cache!

•Recomendado  =  memcached

•Acceder  a  la  BD  es  caro,  muy  caro.

•El  Hardware  es  “gra*s”  en  comparación  con  op*mizar  código  op*mizado.

•Ejemplo  (Facebook):

Page 419: Desarrollo web ágil con Python y Django

caching

•Si  queremos  escalar  nuestro  proyecto  rápidamente....  Cache!

•Recomendado  =  memcached

•Acceder  a  la  BD  es  caro,  muy  caro.

•El  Hardware  es  “gra*s”  en  comparación  con  op*mizar  código  op*mizado.

•Ejemplo  (Facebook):

300+Tb  Memcached

Page 420: Desarrollo web ágil con Python y Django

caching

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)def my_view(request): ...

views

Page 421: Desarrollo web ágil con Python y Django

caching

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)def my_view(request): ...

views

{% load cache %}{% cache 500 sidebar %} .. sidebar ..{% endcache %}

templates

Page 422: Desarrollo web ágil con Python y Django

cachinglow  level

Page 423: Desarrollo web ágil con Python y Django

cachinglow  level

>>> from django.core.cache import cache>>> cache.set('my_key', 'hello, world!', 30)>>> cache.get('my_key')'hello, world!'

•Podemos  cachear  cualquier  *po  de  objeto  que  se  pueda  serializar.•  QuerySets•  Listas•  ...

Page 424: Desarrollo web ágil con Python y Django

memcached  DEMO

Page 425: Desarrollo web ágil con Python y Django

¿Cómo  haríais  un  ranking  de  puntuaciones?

Page 426: Desarrollo web ágil con Python y Django

¿y  para  500k  Usuarios?

Page 427: Desarrollo web ágil con Python y Django

¿y  para  2Millones?

Page 428: Desarrollo web ágil con Python y Django

¿y  para  ++10Millones?

Page 429: Desarrollo web ágil con Python y Django

¿y  para  ++10Millones?

Page 430: Desarrollo web ágil con Python y Django

redis

Page 431: Desarrollo web ágil con Python y Django

redis

•  La  misma  filosoxa  de  memcached  pero  con  grandes  diferencias:•  Atómico•  Persistencia•  Tipos  “ricos”  (list,  sets,  sorted  sets,  etc..)

•  Demo  :  Sistema  de  Ranking•  ¿Cómo  ges*onar  un  ranking  de  más  10Millones  de  usuarios?•  Cada  uuid  es  un  sha1()  -­‐>  40  caracteres.•  Las  Puntuaciones  son  random  entre  0  y  100.000  puntos.•  Los  datos  se  han  introducido  de  manera  aleatoria.

Page 432: Desarrollo web ágil con Python y Django

redis

Page 433: Desarrollo web ágil con Python y Django

redis

•  Introducir  10Millones  de  elementos  en  redis:•  17minutos  -­‐>  1020segundos  -­‐>  ~  0,1  ms  por  insert.•  1.6gb  en  memoria  WTF!!•  int  =  4bytes  *  10M  =  40Millones  de  bytes  =  38Mb•  char(40)  =  40  bytes  *  10M  =  400Millones  de  bytes  =  381Mb•  419Mb  en  total  de  datos  ocupan  1.6gb  en  RAM

Page 434: Desarrollo web ágil con Python y Django

redis

•  Introducir  10Millones  de  elementos  en  redis:•  17minutos  -­‐>  1020segundos  -­‐>  ~  0,1  ms  por  insert.•  1.6gb  en  memoria  WTF!!•  int  =  4bytes  *  10M  =  40Millones  de  bytes  =  38Mb•  char(40)  =  40  bytes  *  10M  =  400Millones  de  bytes  =  381Mb•  419Mb  en  total  de  datos  ocupan  1.6gb  en  RAM

¡Más  que  aceptable  para  dar  solución  a  un  problema  con  10Millones  de  usuarios!

Page 435: Desarrollo web ágil con Python y Django

redis  DEMO

Page 436: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 437: Desarrollo web ágil con Python y Django

Deploying  Django

1. hip://virtualenv.openplans.org/

2. hip://pip.openplans.org/

Page 438: Desarrollo web ágil con Python y Django

Deploying  Django

Virtualenv  +  PIP  1. hip://virtualenv.openplans.org/

2. hip://pip.openplans.org/

Page 439: Desarrollo web ágil con Python y Django

Virtualenv•Independencia  completa  de  las  librerías  del  sitema.

•Cada  proyecto  *ene  su  juego  de  librerías  en  la  versión  que  necesita•Sin  miedo  a  actualizar

•Sin  miedo  a  migrar

•etc...

Page 440: Desarrollo web ágil con Python y Django

Virtualenv•Independencia  completa  de  las  librerías  del  sitema.

•Cada  proyecto  *ene  su  juego  de  librerías  en  la  versión  que  necesita•Sin  miedo  a  actualizar

•Sin  miedo  a  migrar

•etc...

$ virtualenv mi_entorno

crear

Page 441: Desarrollo web ágil con Python y Django

Virtualenv•Independencia  completa  de  las  librerías  del  sitema.

•Cada  proyecto  *ene  su  juego  de  librerías  en  la  versión  que  necesita•Sin  miedo  a  actualizar

•Sin  miedo  a  migrar

•etc...

$ virtualenv mi_entorno

crear

$ source mi_entorno/bin/activate

ac/var

Page 442: Desarrollo web ágil con Python y Django

PIP

•Gestor  de  paquetes  del  siglo  21  :D•Permite  especificar  un  fichero  de  REQUIREMENTS  con  un  listado  de  paquetes  a  instalar.

Page 443: Desarrollo web ágil con Python y Django

PIP

•Gestor  de  paquetes  del  siglo  21  :D•Permite  especificar  un  fichero  de  REQUIREMENTS  con  un  listado  de  paquetes  a  instalar.

Django==1.4.2psycopg2feedparser==4.1stripogram==1.5GChartWrapper==0.8

pip install -E mi_entorno -r REQUIREMENTS

Page 444: Desarrollo web ágil con Python y Django

Nuestro  primer  Virtualenv  +  PIP

a)Crear  un  entorno  virtualb)Instalar  Django==1.0c) Probar  django.VERSION

Page 445: Desarrollo web ágil con Python y Django

El  Stack

Page 446: Desarrollo web ágil con Python y Django

nginx  +  Gunicorn

nginx

gunicorn

•  nginx  [engine  x]  is  a  HTTP  and  reverse  proxy  server.•  Con  una  configuración  muy  sencilla  podremos  u*lizarlo  como  proxy  inverso  a  gunicorn.

•  hGp://gunicorn.org/

•  Servidor  Web  WSGI  implementado  en  Python•  Facilidades  de  puesta  en  marcha  de  proyectos  django•  Fácilmente  configurable  usando  nginx•  hGp://nginx.org/

Page 447: Desarrollo web ágil con Python y Django

nginx  :80

gunicorn

Django

WSGI  Server

Frontend

Deploysencillo

worker  1 worker  2 worker  n

Page 448: Desarrollo web ágil con Python y Django

gunicorn

Django

nginx  :80

web1

gunicorn

Django

nginx  :80

web2

gunicorn

Django

nginx  :80

webn

nginx  :80  :443

varnish

haproxy

frontend1

nginx  :80  :443

varnish

haproxy

frontend2

ipfailover

Deployno  tan  sencillo

Page 449: Desarrollo web ágil con Python y Django

Fabric

Page 450: Desarrollo web ágil con Python y Django

Repe**on  leads  to  boredom,boredom  to  horrifying  mistakes,horrifying  mistakes  to  God-­‐I-­‐wish-­‐I-­‐was-­‐s*ll-­‐bored.

Page 451: Desarrollo web ágil con Python y Django

$ fab deploy -R test

Page 452: Desarrollo web ágil con Python y Django

$ fab deploy -R www

Page 453: Desarrollo web ágil con Python y Django

env.user = "example"env.hosts = ["web1.com", "web2.com", "..."]

def deploy(): run('git pull /home/site/') sudo('service supervisord restart')

Page 454: Desarrollo web ágil con Python y Django

Magia  avanzada

1. Views  avanzadas

2. Context  Processors

3. Custom  Template  Filters  &  Tags4.Middleware

5. Internacionalización

6. Caching7. Despliegue

8. Apps  recomendadas

Page 455: Desarrollo web ágil con Python y Django

Apps

Page 456: Desarrollo web ágil con Python y Django

django-­‐south

Page 457: Desarrollo web ágil con Python y Django

django-­‐south

•  Sistema  inteligente  para  realizar  de  manera  automá*ca  migraciones  de  esquemas.

•¿Que  sucede  si  tengo  un  Modelo  con  100.000  filas  y  quiero  añadir  una  columna?  ...  south!

•Necesito  migrar  el  contenido  desde  mi  an*guo  Modelo  a  uno  nuevo...  south!

•Necesito  que  ...  south!

hGp://south.aeracode.org/

Page 458: Desarrollo web ágil con Python y Django

django-­‐south

$ python manage.py schemamigration website --initial

crear  primer  schema

$ python manage.py schemamigration website --auto

crear  2-­‐*  migración

$ python manage.py migrate

aplicar  migraciones

Page 459: Desarrollo web ágil con Python y Django

django-­‐southhGp://south.aeracode.org/

$ python manage.py schemamigration website --initial

crear  primer  schema

$ python manage.py schemamigration website --auto

crear  2-­‐*  migración

$ python manage.py migrate

aplicar  migraciones

Page 461: Desarrollo web ágil con Python y Django

django-­‐haystack•  “EL”  Sistema  de  búsquedas  para  Django

•  Funciona  con  varios  sistemas  de  Indexación

•  Solr,  Xapian,  Whoosh

•  Features:•  ‘More  like  this’

•Face*ng

•Highligh*ng

•  Spelling  Sugges*on

•  etc...

 h@p://haystacksearch.org

Page 462: Desarrollo web ágil con Python y Django

django-­‐registra/on

 h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

Page 463: Desarrollo web ágil con Python y Django

django-­‐registra/on

•Sistema  completo  para  la  ges*ón  de  usuarios.

•Desde  el  registro,  ac*vación  etc...

•DRY!!

•Instalación  muy  sencilla.

 h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

Page 464: Desarrollo web ágil con Python y Django

django-­‐registra/on

 h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

Page 465: Desarrollo web ágil con Python y Django

django-­‐registra/on/ac*vate/complete//ac*vate/<ac*va*on_key>//  register//  register/complete//  register/closed//  login//  logout//  password/change//  password/change/done//  password/reset//  password/reset/confirm/<token>/  password/reset/complete//  password/reset/done//  reac*vate/

 h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

Page 466: Desarrollo web ágil con Python y Django

django-­‐socialregistra/on

 h@p://github.com/flashingpumpkin/django-­‐socialregistra/on

Page 467: Desarrollo web ágil con Python y Django

django-­‐socialregistra/on

•Configuración  sencilla

•Auten*cación  con:

•twiGer,  facebook,  oauth,  openid

•Integración  perfecta  con  contrib.auth

 h@p://github.com/flashingpumpkin/django-­‐socialregistra/on

Page 468: Desarrollo web ágil con Python y Django

django-­‐debug-­‐toolbar

 h@p://github.com/robhudson/django-­‐debug-­‐toolbar

Page 470: Desarrollo web ágil con Python y Django

•Sistema  de  Tareas  Asíncronas  distribuidas.

•Features:  Colas,  Concurrencia,  Distribuido...

•Muy  fácil  implementación  y  escalable.

•Casos  prác/cos:

•Enviar  un  email

•Calcular  el  karma  de  de  los  usuarios  del  sistema.

•Tareas  programadas  (Limpieza,  Post-­‐procesado,  etc...)

Celery

 h@p://celeryproject.org

Page 471: Desarrollo web ágil con Python y Django

from celery.decorators import task

@taskdef add(x, y): return x + y

>>> result = add.delay(4, 4)>>> result.wait() # wait for and return the result8

Celery

 h@p://celeryproject.org

Page 472: Desarrollo web ágil con Python y Django

from celery.decorators import task

@taskdef add(x, y): return x + y

>>> result = add.delay(4, 4)>>> result.wait() # wait for and return the result8

• Las  Task  son  simples  funciones  (O  class  si  queremos)

• Python  100%  el  retorno  será  el  resultado

• Usamos  el  decorador  @task  para  registrarla

• El  método  .delay  sobre  cualquier  Task  lo  

ejecuta  en  background.

• Podemos  esperar  a  que  un  Worker  ejecute  

la  tarea  o  seguir  haciendo  otras  acciones.

Celery

 h@p://celeryproject.org

Page 473: Desarrollo web ágil con Python y Django

dajaxproject.com

Page 474: Desarrollo web ágil con Python y Django

•  Set  de  liberías  AJAX  para  django.

•  django-­‐dajaxice•  Core  de  comunicación.•  Enviar  información  asyncronamente.

•  django-­‐dajax•  manipular  el  DOM  usando  Python.

dajaxproject.com

Page 475: Desarrollo web ágil con Python y Django

Communica*on  uniforme  entre  el  cliente  y  el    

servidor  .

•  Agnos*co  a  cualquier  Framework  JS.

•  Prototype,  jQuery,  etc...•  Lógica  de  presentación  fuera  de  las  vistas.•  Crossbrowsing.

Obje/vos  dajaxice

Page 476: Desarrollo web ágil con Python y Django

Ejemplo

from django.utils import simplejsonfrom dajaxice.decorators import dajaxice_register

@dajaxice_registerdef my_example(request): return simplejson.dumps({'message':'Hello World'})

Page 477: Desarrollo web ágil con Python y Django

Ejemplo

from django.utils import simplejsonfrom dajaxice.decorators import dajaxice_register

@dajaxice_registerdef my_example(request): return simplejson.dumps({'message':'Hello World'})

Si. es una funcion

que retorna json.

Page 478: Desarrollo web ágil con Python y Django

Ejemplo

function on_whatever(){ Dajaxice.example.my_example(my_js_callback);}

Page 479: Desarrollo web ágil con Python y Django

Ejemplo

function on_whatever(){ Dajaxice.example.my_example(my_js_callback);}

app

function name

callback

Page 480: Desarrollo web ágil con Python y Django

Ejemplo

function my_js_callback(data){ alert(data.message);}

Page 481: Desarrollo web ágil con Python y Django

Ejemplo

function my_js_callback(data){ alert(data.message);}

callback

your stuff

Page 482: Desarrollo web ágil con Python y Django

•  Manipular  el  DOM  usando  Python.

•  Sin  necesidad  de  conocer  JS  en  profundidad.

•  Soporta  Frameworks  como

Obje/vos  dajax

Page 483: Desarrollo web ágil con Python y Django

Ejemplo

from dajax.core.Dajax import Dajax

def assign_test(request): dajax = Dajax() dajax.assign('#list li','innerHTML','Hello!') dajax.add_css_class('#list li','new') ... return dajax.json()

Page 484: Desarrollo web ágil con Python y Django

Ejemplo

from dajax.core.Dajax import Dajax

def assign_test(request): dajax = Dajax() dajax.assign('#list li','innerHTML','Hello!') dajax.add_css_class('#list li','new') ... return dajax.json()

tus acciones

Page 485: Desarrollo web ágil con Python y Django

Ejemplo

function on_whatever(){ Dajaxice.app.assign_test(Dajax.process);}

Page 486: Desarrollo web ágil con Python y Django

Ejemplo

function on_whatever(){ Dajaxice.app.assign_test(Dajax.process);}

Dajax callback

Page 487: Desarrollo web ágil con Python y Django

DEMO

Page 488: Desarrollo web ágil con Python y Django

django-­‐tastypie

h@p://django-­‐tastypie.readthedocs.org/

Page 489: Desarrollo web ágil con Python y Django

django-­‐tastypie

•  Framework  para  crear  APIs  RESTful

•  Muy  fácil  instalación

•  Serialización  a:

•JSON,  XML,  YAML  bplist  ...

•OAuth

h@p://django-­‐tastypie.readthedocs.org/

Page 490: Desarrollo web ágil con Python y Django

Sentry    -­‐  getsentry.com

 h@p://getsentry.com

Page 491: Desarrollo web ágil con Python y Django

django-­‐command-­‐extensions

 h@p://code.google.com/p/django-­‐command-­‐extensions/

Page 492: Desarrollo web ágil con Python y Django

django-­‐command-­‐extensions

•Extensión  para  “manage.py”

•Muchas  u*lidades  para  el  día  a  día

•Una  de  las  mejores:  graph_models

•Usando  GraphViz  genera  un  modelo  relacional  de  los  

modelos  de  nuestro  proyecto.

 h@p://code.google.com/p/django-­‐command-­‐extensions/

Page 493: Desarrollo web ágil con Python y Django

django-­‐command-­‐extensions

Page 494: Desarrollo web ágil con Python y Django

django-­‐command-­‐extensions

Page 495: Desarrollo web ágil con Python y Django

django-­‐command-­‐extensions

Page 496: Desarrollo web ágil con Python y Django

django-­‐command-­‐extensions

Page 498: Desarrollo web ágil con Python y Django

 h@p://flask.pocoo.org

from flask import Flaskapp = Flask(__name__)

@app.route("/")def hello(): return "Hello World!"

if __name__ == "__main__": app.run()

$ pip install Flask$ python hello.py * Running on http://localhost:5000/

Page 499: Desarrollo web ágil con Python y Django

import tornado.ioloopimport tornado.web

class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world")

application = tornado.web.Application([ (r"/", MainHandler),])

if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()

 h@p://tornadoweb.org

•  real-­‐/me  •  non-­‐blocking  •  epoll

Page 500: Desarrollo web ágil con Python y Django

Sublime  Text  2

 h@p://www.sublimetext.com/2

Page 502: Desarrollo web ágil con Python y Django

La  punta  del  iceberg

Page 504: Desarrollo web ágil con Python y Django

How  to  ...  using  Django?