Download - Desarrollo web ágil con Python y Django
![Page 3: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/3.jpg)
![Page 4: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/4.jpg)
![Page 5: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/5.jpg)
![Page 6: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/6.jpg)
![Page 7: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/7.jpg)
Evaluación
![Page 8: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/8.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/9.jpg)
![Page 10: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/10.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/11.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/12.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/13.jpg)
El Intérprete
![Page 14: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/14.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/15.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/16.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/17.jpg)
Tipos de datos
h@p://docs.python.org/library/stdtypes.html
object
![Page 18: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/18.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/19.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/20.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/21.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/22.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/23.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/24.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/25.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/26.jpg)
Operadores
h@p://docs.python.org/library/operator.html
![Page 27: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/27.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/28.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/29.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/30.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/31.jpg)
Usos frecuentes: list
![Page 32: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/32.jpg)
Usos frecuentes: list>>> nums = [1, 2, 3]>>> nums[0]1
![Page 33: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/33.jpg)
Usos frecuentes: list>>> nums = [1, 2, 3]>>> nums[0]1
>>> 2 in numsTrue
![Page 34: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/34.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/35.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/36.jpg)
Usos frecuentes: str
![Page 37: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/37.jpg)
Usos frecuentes: str>>> "Python mola"[1:4]'yth'
![Page 38: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/38.jpg)
Usos frecuentes: str>>> "Python mola"[1:4]'yth'
>>> "Python mola".find("mola")7
![Page 39: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/39.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/40.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/41.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/42.jpg)
Usos frecuentes: dict
![Page 43: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/43.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/44.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/45.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/46.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/47.jpg)
Usos frecuentes: str %
![Page 48: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/48.jpg)
Usos frecuentes: str %
>>> "%s es muy sabio" % "Hycker"'Hycker es muy sabio'
![Page 49: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/49.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/50.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/51.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/52.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/53.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/54.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/55.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/56.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/57.jpg)
{}Estructuras
![Page 58: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/58.jpg)
{}Estructuras
![Page 59: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/59.jpg)
>>> 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/60.jpg)
>>> 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/61.jpg)
• 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 62: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/62.jpg)
def my_first_function(p1, p2): return "Hello World!"
Funciones
MinúsculasPalabras separadas por _Evitar camelCase
![Page 63: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/63.jpg)
def my_first_function(p1, p2): return "Hello World!"
12
3
Funciones
MinúsculasPalabras separadas por _Evitar camelCase
PEP 8
![Page 64: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/64.jpg)
Conversión de /pos
h@p://docs.python.org/library/func/ons.html
![Page 65: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/65.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/66.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/67.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/68.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/69.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/70.jpg)
Funciones comunes
h@p://docs.python.org/library/func/ons.html
![Page 71: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/71.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/72.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/73.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/74.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/75.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/76.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/77.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/78.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/79.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/80.jpg)
Funciones de ayuda
![Page 81: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/81.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/82.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/83.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/84.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/85.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/86.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/87.jpg)
$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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/88.jpg)
$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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/89.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/90.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/91.jpg)
Prueba de sentencias en consola
![Page 92: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/92.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/93.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/94.jpg)
Ejemplo PythonhGp://bit.ly/ejemplo-‐python
![Page 95: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/95.jpg)
Ejercicio PythonhGp://bit.ly/ejercicio-‐python
![Page 96: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/96.jpg)
SolucioneshGp://bit.ly/ejercicio-‐resuelto
hGp://bit.ly/ejercicio-‐resuelto-‐awesome
![Page 97: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/97.jpg)
![Page 98: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/98.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/99.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/100.jpg)
Frameworks web
![Page 101: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/101.jpg)
Django: Qué y dónde
![Page 102: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/102.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/103.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/104.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/105.jpg)
La comunidad
![Page 106: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/106.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/107.jpg)
¿Quién usa Django?
![Page 108: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/108.jpg)
¿Quién usa Django?
![Page 109: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/109.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/110.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/111.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/112.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/113.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/114.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/115.jpg)
All Right?
![Page 116: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/116.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/117.jpg)
![Page 118: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/118.jpg)
Bienvenidos al mundo de Oz
![Page 119: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/119.jpg)
* 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/120.jpg)
* 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/121.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/122.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/123.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/124.jpg)
Let’s enjoy
![Page 125: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/125.jpg)
Crear nuestro proyectode 5 ficheros ;-‐)
![Page 126: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/126.jpg)
Crear nuestro proyecto
$ django-admin.py startproject dwitter
de 5 ficheros ;-‐)
![Page 127: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/127.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/128.jpg)
sesngs.py
![Page 129: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/129.jpg)
Arrancar nuestro proyectode 5 ficheros ;-‐)
![Page 130: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/130.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/131.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/132.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/133.jpg)
MVC en Django
Modelo = Model Vista = Template Controlador = URL+View
![Page 134: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/134.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/135.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/136.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/137.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/138.jpg)
![Page 139: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/139.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/140.jpg)
¡Recuerda!: MVC
![Page 141: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/141.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/142.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/143.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/144.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/145.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/146.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/147.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/148.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/149.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/150.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/151.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/152.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/153.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/154.jpg)
Templates: TipTEMPLATE_DIRS = ( '/home/django/templates',)
senngs.pya)
![Page 155: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/155.jpg)
Templates: TipTEMPLATE_DIRS = ( '/home/django/templates',)
senngs.py Reusable
apps?a)
![Page 156: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/156.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/157.jpg)
¡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 158: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/158.jpg)
h@p://github.com/enjoydjango/dwi@er
![Page 159: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/159.jpg)
Git
![Page 160: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/160.jpg)
Git
Quiero ir a...
¿Donde estoy?
1ª
![Page 161: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/161.jpg)
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
1ª
![Page 162: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/162.jpg)
Git
Ignorar todos los cambios *
* Si no habéis commiteado nada
![Page 163: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/163.jpg)
Git
$ git reset --hard HEAD $ git clean -fd
Ignorar todos los cambios *
* Si no habéis commiteado nada
![Page 164: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/164.jpg)
h@p://github.com/enjoydjango/dwi@er
![Page 165: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/165.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/166.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/167.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/168.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/169.jpg)
Filters y Tags
![Page 170: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/170.jpg)
Filters y Tags
![Page 171: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/171.jpg)
Filters y Tags
{{ varible|filter }}filter
![Page 172: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/172.jpg)
Filters y Tags
{{ varible|filter }}filter
{% tag var1 var2 %}inline tag
![Page 173: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/173.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/174.jpg)
Templates: tags {% %}
![Page 175: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/175.jpg)
Templates: tags {% %}
{% comment %} Bu! {% endcomment %}comment
![Page 176: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/176.jpg)
Templates: tags {% %}
{% comment %} Bu! {% endcomment %}comment
for {% for elemento in lista %} <li>{{ elemento }}<li>{% endfor %}
![Page 177: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/177.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/178.jpg)
Templates: tags {% %}
![Page 179: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/179.jpg)
Templates: tags {% %}cycle {% for elemento in lista %}
<li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>{% endfor %}
![Page 180: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/180.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/181.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/182.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/183.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/184.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/185.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/186.jpg)
Templates: Filters
![Page 187: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/187.jpg)
Templates: Filters{'username': 'Juan es majo'}
{{ username|length }}length 12
![Page 188: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/188.jpg)
Templates: Filters{'username': 'Juan es majo'}
{{ username|length }}length 12
{{ username|cut }}cut Juanesmajo
![Page 189: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/189.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/190.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/191.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/192.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/193.jpg)
Templates: Filters
![Page 194: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/194.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/195.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/196.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/197.jpg)
Templates: Filters
![Page 198: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/198.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/199.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/200.jpg)
Templates: Filters{'lista': ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]}
![Page 201: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/201.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/202.jpg)
Templates: Filters
![Page 203: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/203.jpg)
Templates: Filters{'value': 123456789}
{{ value|add:”1” }}add 123456790
![Page 204: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/204.jpg)
Templates: Filters{'value': 123456789}
{{ value|add:”1” }}add 123456790
{{ value|filesizeformat }}filesizeformat 117.7MB
![Page 205: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/205.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/206.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/207.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/208.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/209.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/210.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/211.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/212.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/213.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/214.jpg)
Modelos
![Page 215: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/215.jpg)
¿SQL?
![Page 216: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/216.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/217.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/218.jpg)
12 lineas de Python... ¬_¬
![Page 219: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/219.jpg)
ORM (Object-‐RelaHonal mapping)
![Page 220: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/220.jpg)
ORM (Object-‐RelaHonal mapping)
![Page 221: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/221.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/222.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/223.jpg)
Fucking Ninjas!
![Page 224: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/224.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/225.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/226.jpg)
Fucking Awesome Ninjas!
![Page 227: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/227.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/228.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/229.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/230.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/231.jpg)
¿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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/232.jpg)
¿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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/233.jpg)
¿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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/234.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/235.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/236.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/237.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/238.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/239.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/240.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/241.jpg)
¿Cuantos sistemas de AutenHcación habéis programado?
![Page 242: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/242.jpg)
¿Alguno era mejor que el anterior? ;-‐)
![Page 243: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/243.jpg)
contrib.auth puede ser el úlHmo :D
![Page 244: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/244.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/245.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/246.jpg)
BD Lista para usarse
![Page 247: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/247.jpg)
BD Lista para usarse
![Page 248: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/248.jpg)
Nuestro primer modelo
a)Hacer syncdb
![Page 249: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/249.jpg)
![Page 250: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/250.jpg)
Previo: Clases del ORM
ts = Publisher.objects.all()
Model
Manager
QuerySet
![Page 251: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/251.jpg)
INSERT
![Page 252: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/252.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/253.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/254.jpg)
UPDATE
![Page 255: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/255.jpg)
UPDATE
>>> ...>>> p.id52>>> p.name = 'Apress Publishing'>>> p.save()
o.save()
1
![Page 256: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/256.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/257.jpg)
DELETE
![Page 258: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/258.jpg)
DELETE
>>> ...>>> p.id52>>> p.delete()
o.delete()
1
![Page 259: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/259.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/260.jpg)
SELECT de 1 resultado
![Page 261: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/261.jpg)
SELECT de 1 resultado
>>> Publisher.objects.get(name="Apress")<Publisher: Apress>
.get(...)
![Page 262: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/262.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/263.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/264.jpg)
SELECT de N resultados
![Page 265: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/265.jpg)
SELECT de N resultados
>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: O'Reilly>]
.all()
![Page 266: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/266.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/267.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/268.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/269.jpg)
get(), filter() y exclude()
![Page 270: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/270.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/271.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/272.jpg)
ORDER BY
![Page 273: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/273.jpg)
ORDER BY
>>> Publisher.objects.order_by("name")[<Publisher: Apress>, <Publisher: O'Reilly>]
.order_by(...)
![Page 274: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/274.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/275.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/276.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/277.jpg)
Slicing
![Page 278: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/278.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/279.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/280.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/281.jpg)
Related Objects
![Page 282: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/282.jpg)
Related ObjectsOneToOneField
class Coche(models.Model): motor = OneToOneField(Motor)
class Motor(models.Model): ...
1
1
![Page 283: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/283.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/284.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/285.jpg)
Related Objects
![Page 286: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/286.jpg)
Related ObjectsForeignKeyField
class Blog(models.Model): ...
class Post(models.Model): blog = ForeignKeyField(Blog)
1
n
![Page 287: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/287.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/288.jpg)
Related Objects
![Page 289: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/289.jpg)
Related ObjectsManyToManyField
class Post(models.Model): tags = ManyToManyField(Tag)
class Tag(models.Model): ...
n
m
![Page 290: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/290.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/291.jpg)
Related Objects
![Page 292: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/292.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/293.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/294.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/295.jpg)
Y la guinda final: ¡Todo es LAZY!
![Page 296: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/296.jpg)
Laziness
![Page 297: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/297.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/298.jpg)
Nota: __unicode__()
![Page 299: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/299.jpg)
Nota: __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
![Page 300: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/300.jpg)
Nota: __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
![Page 301: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/301.jpg)
Nota: __unicode__()>>> Publisher.objects.all()[<Publisher: Publisher object>]
![Page 302: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/302.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/303.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/304.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/305.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/306.jpg)
Profiles
![Page 307: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/307.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/308.jpg)
Profile
models.py
![Page 309: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/309.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/310.jpg)
Profile
•Donde tengamos el User tendremos el Profile.•Donde tengamos el Profile, tendremos el User.
![Page 311: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/311.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/312.jpg)
1 User = 1 Profile ¿Cuándo se crea un User?
![Page 313: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/313.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/314.jpg)
Signals
![Page 315: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/315.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/316.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/317.jpg)
Followers
![Page 318: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/318.jpg)
Profilemodels.py
![Page 319: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/319.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/320.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/321.jpg)
1,2,3 Borrar la BD.... 1,2,3... Borrar la BD
![Page 322: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/322.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/323.jpg)
CRUD: Create, Retrieve, Update & Delete
![Page 324: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/324.jpg)
django.contrib.admin
1
2
3
![Page 325: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/325.jpg)
django.contrib.admin
1
2
3
![Page 326: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/326.jpg)
django.contrib.admin
1
![Page 327: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/327.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/328.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/329.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/330.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/331.jpg)
Actualizando la BD
![Page 332: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/332.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/333.jpg)
¿Y nuestra app?
?
![Page 334: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/334.jpg)
¿Y nuestra app?
![Page 335: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/335.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/336.jpg)
Instalar Admin
a)Configurar urls.pyb)Configurar sesngs.pyc) Hacer syncdb
![Page 337: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/337.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/338.jpg)
Fixtures
![Page 339: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/339.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/340.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/341.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/342.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/343.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/344.jpg)
Formularios
![Page 345: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/345.jpg)
Clases involucradas
![Page 346: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/346.jpg)
Clases involucradasWidget Componente visual equivalente a HTML
TextInput
CheckboxInput
<input type='text'...>
<input type='checkbox'...>
![Page 347: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/347.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/348.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/349.jpg)
Fields
![Page 350: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/350.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/351.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/352.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/353.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/354.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/355.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/356.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/357.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/358.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/359.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/360.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/361.jpg)
Forms a parHr de Models: El COLMO del DRY
![Page 362: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/362.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/363.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/364.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/365.jpg)
Í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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/366.jpg)
Magia avanzada
![Page 367: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/367.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/368.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/369.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/370.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/371.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/372.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/373.jpg)
Views avanzadas¿Dónde somos capaces de reu/lizar código entre apps?
![Page 374: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/374.jpg)
Views avanzadas¿Dónde somos capaces de reu/lizar código entre apps?
![Page 375: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/375.jpg)
Views avanzadas¿Dónde somos capaces de reu/lizar código entre apps?
![Page 376: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/376.jpg)
Views avanzadas¿Dónde somos capaces de reu/lizar código entre apps?
![Page 377: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/377.jpg)
![Page 378: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/378.jpg)
NUNCAINFRAVALORÉIS
EL PODERDE UN PONYROSA
![Page 379: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/379.jpg)
Views avanzadas¿Dónde somos capaces de reu/lizar código entre apps?
![Page 380: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/380.jpg)
Views avanzadas¿Dónde somos capaces de reu/lizar código entre apps?
![Page 381: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/381.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/382.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/383.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/384.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/385.jpg)
Context Processors
!
!
!
!
![Page 386: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/386.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/387.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/388.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/389.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/390.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/391.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/392.jpg)
Template LibraryNos permite extender el sistema de templates
de Django con Filters y Tags propios
![Page 393: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/393.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/394.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/395.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/396.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/397.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/398.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/399.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/400.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/401.jpg)
SimpleTagsEjemplo: Devolver la hora actual formateada.
{% current_time "%Y-%m-%d %I:%M %p" %}
![Page 402: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/402.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/403.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/404.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/405.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/406.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/407.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/408.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/409.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/410.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/411.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/412.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/413.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/414.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/415.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/416.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/417.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/418.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/419.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/420.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/421.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/422.jpg)
cachinglow level
![Page 423: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/423.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/424.jpg)
memcached DEMO
![Page 425: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/425.jpg)
¿Cómo haríais un ranking de puntuaciones?
![Page 426: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/426.jpg)
¿y para 500k Usuarios?
![Page 427: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/427.jpg)
¿y para 2Millones?
![Page 428: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/428.jpg)
¿y para ++10Millones?
![Page 429: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/429.jpg)
¿y para ++10Millones?
![Page 430: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/430.jpg)
redis
![Page 431: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/431.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/432.jpg)
redis
![Page 433: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/433.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/434.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/435.jpg)
redis DEMO
![Page 436: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/436.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/437.jpg)
Deploying Django
1. hip://virtualenv.openplans.org/
2. hip://pip.openplans.org/
![Page 438: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/438.jpg)
Deploying Django
Virtualenv + PIP 1. hip://virtualenv.openplans.org/
2. hip://pip.openplans.org/
![Page 439: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/439.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/440.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/441.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/442.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/443.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/444.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/445.jpg)
El Stack
![Page 446: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/446.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/447.jpg)
nginx :80
gunicorn
Django
WSGI Server
Frontend
Deploysencillo
worker 1 worker 2 worker n
![Page 448: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/448.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/449.jpg)
Fabric
![Page 450: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/450.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/451.jpg)
$ fab deploy -R test
![Page 452: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/452.jpg)
$ fab deploy -R www
![Page 453: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/453.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/454.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/455.jpg)
Apps
![Page 456: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/456.jpg)
django-‐south
![Page 457: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/457.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/458.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/459.jpg)
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 460: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/460.jpg)
django-‐haystack
h@p://haystacksearch.org
![Page 461: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/461.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/462.jpg)
django-‐registra/on
h@p://bitbucket.org/ubernostrum/django-‐registra/on/
![Page 463: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/463.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/464.jpg)
django-‐registra/on
h@p://bitbucket.org/ubernostrum/django-‐registra/on/
![Page 465: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/465.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/466.jpg)
django-‐socialregistra/on
h@p://github.com/flashingpumpkin/django-‐socialregistra/on
![Page 467: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/467.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/468.jpg)
django-‐debug-‐toolbar
h@p://github.com/robhudson/django-‐debug-‐toolbar
![Page 469: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/469.jpg)
Celery
h@p://celeryproject.org
![Page 470: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/470.jpg)
•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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/471.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/472.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/473.jpg)
dajaxproject.com
![Page 474: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/474.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/475.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/476.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/477.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/478.jpg)
Ejemplo
function on_whatever(){ Dajaxice.example.my_example(my_js_callback);}
![Page 479: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/479.jpg)
Ejemplo
function on_whatever(){ Dajaxice.example.my_example(my_js_callback);}
app
function name
callback
![Page 480: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/480.jpg)
Ejemplo
function my_js_callback(data){ alert(data.message);}
![Page 481: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/481.jpg)
Ejemplo
function my_js_callback(data){ alert(data.message);}
callback
your stuff
![Page 482: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/482.jpg)
• 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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/483.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/484.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/485.jpg)
Ejemplo
function on_whatever(){ Dajaxice.app.assign_test(Dajax.process);}
![Page 486: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/486.jpg)
Ejemplo
function on_whatever(){ Dajaxice.app.assign_test(Dajax.process);}
Dajax callback
![Page 487: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/487.jpg)
DEMO
![Page 488: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/488.jpg)
django-‐tastypie
h@p://django-‐tastypie.readthedocs.org/
![Page 489: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/489.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/490.jpg)
Sentry -‐ getsentry.com
h@p://getsentry.com
![Page 491: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/491.jpg)
django-‐command-‐extensions
h@p://code.google.com/p/django-‐command-‐extensions/
![Page 492: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/492.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/493.jpg)
django-‐command-‐extensions
![Page 494: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/494.jpg)
django-‐command-‐extensions
![Page 495: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/495.jpg)
django-‐command-‐extensions
![Page 496: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/496.jpg)
django-‐command-‐extensions
![Page 497: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/497.jpg)
Alterna/vas
h@p://flask.pocoo.org h@p://tornadoweb.org
![Page 498: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/498.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/499.jpg)
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](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/500.jpg)
Sublime Text 2
h@p://www.sublimetext.com/2
![Page 501: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/501.jpg)
Pycharm
h@p://www.jetbrains.com/pycharm
![Page 502: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/502.jpg)
La punta del iceberg
![Page 503: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/503.jpg)
h@p://www.djangobook.com
![Page 504: Desarrollo web ágil con Python y Django](https://reader031.vdocumento.com/reader031/viewer/2022012913/555ad427d8b42a62528b479e/html5/thumbnails/504.jpg)
How to ... using Django?