Python + Django

Python + Django

Django module at the MSc in Development and Integration of Software Solutions. Deusto, Bilbao - Spain.

2e19e78ec961cd9c60642ce7fe9f8c68?s=128

Jorge Bastida

May 07, 2012
Tweet

Transcript

  1. Jorge  Bas*da me@jorgebas*da.com @jorgebas*da Jaime  Irurzun jaime@irurzun.com @jaimeirurzun

  2. Jorge  Bas*da me@jorgebas*da.com @jorgebas*da Jaime  Irurzun   jaime@irurzun.com @jaimeirurzun

  3. None
  4. None
  5. None
  6. None
  7. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  8. None
  9. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  10. • 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,  ...
  11. Instalación $ sudo apt-get install python http://www.python.org/download/ Snow  Leopard  incluye

     las  versiones  2.5.4  y  2.6.1
  12. El  Intérprete

  13. El  Intérprete $ python holamundo.py hola mundo! $ Modo  Batch

    #!/usr/bin/env python print "hola mundo!" holamundo.py
  14. El  Intérprete $ python Python 2.6.5 (r265:79063, Apr 16 2010,

    13:09:56) [GCC 4.4.3] on linux2 Type "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 python print "hola mundo!" holamundo.py
  15. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  16. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object

  17. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long
  18. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long True False bool
  19. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long True False bool 'spam' "guido's" """n lines""" str
  20. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long True False bool 'spam' "guido's" """n lines""" str [1, [2, 'three'], 4] list
  21. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long True False bool 'spam' "guido's" """n lines""" str [1, [2, 'three'], 4] list {'food': 'spam', 'taste': 'yum'} dict
  22. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long True False bool 'spam' "guido's" """n lines""" str [1, [2, 'three'], 4] list {'food': 'spam', 'taste': 'yum'} dict (1, 'spam', 4, 'U') tuple
  23. Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object 1234 3.1415 int float 35L

    long True False bool 'spam' "guido's" """n lines""" str [1, [2, 'three'], 4] list {'food': 'spam', 'taste': 'yum'} dict (1, 'spam', 4, 'U') tuple ¡Tipado   dinámico!
  24. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  25. Operadores  h@p://docs.python.org/library/operator.html

  26. Operadores numéricos a + b a - b a *

    b a / b a % b -a +a a ** b  h@p://docs.python.org/library/operator.html
  27. Operadores numéricos a + b a - b a *

    b a / b a % b -a +a a ** b comparadores a < b a <= b a > b a >= b a == b a != b  h@p://docs.python.org/library/operator.html
  28. Operadores numéricos a + b a - b a *

    b a / b a % b -a +a a ** b comparadores a < 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
  29. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  30. Usos  frecuentes:  list

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

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

    nums[0] 1 >>> 2 in nums True
  33. Usos  frecuentes:  list >>> nums = [1, 2, 3] >>>

    nums[0] 1 >>> nums.append(4) >>> print nums [1, 2, 3, 4] >>> 2 in nums True
  34. Usos  frecuentes:  list >>> nums = [1, 2, 3] >>>

    nums[0] 1 >>> nums.append(4) >>> print nums [1, 2, 3, 4] >>> 2 in nums True >>> len(nums) 4
  35. Usos  frecuentes:  str

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

  37. Usos  frecuentes:  str >>> "Python mola"[1:4] 'yth' >>> "Python mola".find("mola")

    7
  38. Usos  frecuentes:  str >>> "Python mola"[1:4] 'yth' >>> "Python mola".find("mola")

    7 >>> "Python mola".replace("Python", "PHP no") 'PHP no mola'
  39. 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']
  40. 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"
  41. Usos  frecuentes:  dict

  42. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24}

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

    >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24] >>> user['age'] 24 >>> user.get('age', 20) 24
  44. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24}

    >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24] >>> user['age'] 24 >>> user.get('age', 20) 24 >>> 'nick' in user True
  45. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24}

    >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24] >>> user['age'] 24 >>> user.get('age', 20) 24 >>> 'nick' in user True >>> user.update({'nick': 'alatar', 'age': 25}) >>> user {'nick': 'alatar', 'age': 25}
  46. Usos  frecuentes:  str  %

  47. Usos  frecuentes:  str  % >>> "%s es muy sabio" %

    "Hycker" 'Hycker es muy sabio'
  48. Usos  frecuentes:  str  % >>> "%s es muy sabio" %

    "Hycker" 'Hycker es muy sabio' >>> "%s sabe %i idiomas" % ("Hycker", 5) 'Hycker sabe 5 idiomas'
  49. 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'
  50. 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ódulos 1. 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
  51. 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ódulos 1. 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 2 3
  52. 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
  53. Módulos 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 ...
  54. Módulos 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 ... >>> from juego.personajes.mario import Mario >>> Mario() >>> from juego.personajes.mario import * >>> Mario() >>> from juego import personajes >>> personajes.mario.Mario()
  55. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  56. {} Estructuras

  57. {} Estructuras

  58. >>> from __future__ import braces File "<stdin>", line 1 SyntaxError:

    not a chance Identación 4  Espac/os  para  la  identación
  59. >>> from __future__ import braces File "<stdin>", line 1 SyntaxError:

    not a chance Identación 4  Espac/os  para  la  identación PEP 8
  60. •  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/
  61. def my_first_function(p1, p2): return "Hello World!" Funciones Minúsculas Palabras  separadas

     por  _ Evitar  camelCase
  62. def my_first_function(p1, p2): return "Hello World!" 1 2 3 Funciones

    Minúsculas Palabras  separadas  por  _ Evitar  camelCase PEP 8
  63. Conversión  de  /pos  h@p://docs.python.org/library/func/ons.html

  64. Conversión  de  /pos >>> int(1.3) 1  h@p://docs.python.org/library/func/ons.html

  65. Conversión  de  /pos >>> str(2) '2' >>> int(1.3) 1  h@p://docs.python.org/library/func/ons.html

  66. Conversión  de  /pos >>> str(2) '2' >>> int(1.3) 1 >>>

    float(1) 1.0  h@p://docs.python.org/library/func/ons.html
  67. 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
  68. 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
  69. Funciones  comunes  h@p://docs.python.org/library/func/ons.html

  70. Funciones  comunes >>> len("Python Mola") 11 >>> len([1,2,3,4]) 4  h@p://docs.python.org/library/func/ons.html

  71. 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
  72. 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
  73. 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
  74. Funciones  interesantes Son  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html

  75. 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
  76. 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
  77. 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
  78. 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
  79. Funciones  de  ayuda

  80. 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']
  81. 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)
  82. 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
  83. 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) camelCase PEP 8
  84. El  operador  () • Es  importante  diferenciar: funcion    

     vs      funcion() Clase              vs        Clase() • El  operador  ()  permite: • Invocar  funciones: • Instanciar  clases: resultado = funcion() objeto = Clase("param1")
  85. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  86. $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
  87. $count = 0; while ($count < 5) { echo "Number

    ".$count; $count+=1; } count = 0 while count < 5: print "Number %i" % count count+=1 Sentencias:  while
  88. for ($i=0; $i < 5; $i++) { echo "Number ".$count;

    } for i in range(4): print "Number %i" % count Sentencias:  for
  89. try { $result = 3 / 0; } catch (Exception

    $e) { echo "Division by Zero" } try: result = 3 / 0 except: print "Division by Zero" Sentencias:  try-­‐except
  90. Prueba  de  sentencias  en  consola

  91. •  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
  92. •  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
  93. Ejemplo  Python hFp://bit.ly/ejemplo-­‐python    

  94. Ejercicio  Python hFp://bit.ly/ejercicio-­‐python    

  95. Soluciones hFp://bit.ly/ejercicio-­‐resuelto hFp://bit.ly/ejercicio-­‐resuelto-­‐awesome

  96. None
  97. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  98. Evolución  de  la  Web Desarrollo  Web 1ª  Generación 2ª  Generación

    3ª  Generación HTML CGI PHP ASP JSP ... Django Rails Symfony ...
  99. Frameworks  web

  100. Django:  Qué  y  dónde

  101. •  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
  102. •  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
  103. •  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/
  104. La  comunidad

  105. La  comunidad • django-­‐users 22.000  miembros • django-­‐developers 7.000  miembros

    • djangoproject.com +500.000  visitas  únicas  mensuales
  106. ¿Quién  usa  Django?

  107. ¿Quién  usa  Django?

  108. 1.  Instalación  Python $ sudo apt-get install python http://www.python.org/download/ Snow

     Leopard  incluye  las  versiones  2.5.4  y  2.6.1
  109. 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
  110. 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
  111. •  Vamos  a  uHlizar  SQLite  por  comodidad •  Desde  Python

     2.5  podemos  uHlizar  sqlite    sin  instalar  nada. 2.  Instalación  SGBD
  112. •  Vamos  a  uHlizar  SQLite  por  comodidad •  Desde  Python

     2.5  podemos  uHlizar  sqlite    sin  instalar  nada. 2.  Instalación  SGBD
  113. 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
  114. All  Right?

  115. All  Right? >>> import django >>> django.VERSION (1, 4, 0,

    'final', 0) >>> import django Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named django
  116. None
  117. Bienvenidos  al  mundo  de  Oz

  118. *  Incluida  la  carpeta  del  proyecto Ficheros  y  Carpetas ¿Es

     Django  tán  simple  y  fácil  de  usar?
  119. *  Incluida  la  carpeta  del  proyecto Ficheros  y  Carpetas Ficheros

    Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar?
  120. 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?
  121. 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?
  122. 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?
  123. Let’s  enjoy

  124. Crear  nuestro  proyecto de  5  ficheros  ;-­‐)

  125. Crear  nuestro  proyecto $ django-admin startproject dwitter de  5  ficheros

     ;-­‐)
  126. Crear  nuestro  proyecto $ django-admin 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  ;-­‐)
  127. sesngs.py

  128. Arrancar  nuestro  proyecto de  5  ficheros  ;-­‐)

  129. Arrancar  nuestro  proyecto de  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.
  130. Arrancar  nuestro  proyecto de  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.
  131. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  132. MVC  en  Django Modelo  =  Model Vista  =  Template Controlador

     =  URL+View
  133. 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 hFp://mysite.com/about/ html ... ¿urlpaFerns?
  134. 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()
  135. URLs  y  Vistas Ejemplo  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 HttpResponse from datetime import datetime def hora_actual(request): now = datetime.now() html = "Son las %s." % now return HttpResponse(html) urls.py views.py
  136. 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 HttpResponse from 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
  137. None
  138. 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 HttpResponse from 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
  139. ¡Recuerda!:  MVC

  140. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  141. Templates • Separan  la  lógica  de  presentación  a  una  capa

     independiente. • Ficheros  independientes  (.html) • Lenguaje  independiente  (¡para  diseñadores!)
  142. 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  HFpResponse  (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."
  143. Templates from django.http import HttpResponse from django.template import Template, Context

    from 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
  144. Templates • Segunda  aproximación  al  obje*vo:  open(),  read(),  close() from

    django.http import HttpResponse from django.template import Template, Context from 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)
  145. Templates • Segunda  aproximación  al  obje*vo:  open(),  read(),  close() from

    django.http import HttpResponse from django.template import Template, Context from 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)
  146. Templates • Segunda  aproximación  al  obje*vo:  open(),  read(),  close() from

    django.http import HttpResponse from django.template import Template, Context from 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!
  147. Templates • Tercera  aproximación  al  obje*vo:  get_template() from django.http import

    HttpResponse from django.template.loader import get_template from django.template import Context from 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
  148. Templates • Tercera  aproximación  al  obje*vo:  get_template() TEMPLATE_DIRS = (

    '/home/django/templates', ) senngs.py from django.http import HttpResponse from django.template.loader import get_template from django.template import Context from 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)
  149. Templates • Tercera  aproximación  al  obje*vo:  get_template() TEMPLATE_DIRS = (

    '/home/django/templates', ) senngs.py from django.http import HttpResponse from django.template.loader import get_template from django.template import Context from 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...
  150. Templates • Obje*vo  alcanzado:  render() from django.shortcuts import render from

    datetime import datetime def hora_actual(request): now = datetime.now() return render(request, 'hora.html', {'hora': now})
  151. Templates • Obje*vo  alcanzado:  render() from django.shortcuts import render from

    datetime import datetime def hora_actual(request): now = datetime.now() return render(request, 'hora.html', {'hora': now}) Boring...?
  152. Templates • Obje*vo  alcanzado:  render() from django.shortcuts import render from

    datetime import datetime def hora_actual(request): now = datetime.now() return render(request, 'hora.html', {'hora': now}) AWESOME!
  153. Templates:  Tip TEMPLATE_DIRS = ( '/home/django/templates', ) senngs.py a)

  154. Templates:  Tip TEMPLATE_DIRS = ( '/home/django/templates', ) senngs.py Reusable  

    apps? a)
  155. Templates:  Tip TEMPLATE_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:
  156. ¡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)
  157. h@p://github.com/enjoydjango/dwi@er

  158. Git

  159. Git Quiero  ir  a... ¿Donde  estoy? 1ª

  160. 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ª
  161. Git Ignorar  todos  los  cambios  * *  Si  no  habéis

     commiteado  nada
  162. Git $ git reset --hard HEAD $ git clean -fd

    Ignorar  todos  los  cambios  * *  Si  no  habéis  commiteado  nada
  163. h@p://github.com/enjoydjango/dwi@er

  164. Tarea:  URLs  y  Vistas a) 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
  165. 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
  166. 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.
  167. Templates:  {{}} <html> <head>Ejemplo templates</head> <body> Hola, {{ username }}.

    </body> </html> {'username': 'juan'} <html> <head>Ejemplo templates</head> <body> Hola, juan. </body> </html>
  168. Filters  y  Tags

  169. Filters  y  Tags

  170. Filters  y  Tags {{ varible|filter }} filter

  171. Filters  y  Tags {{ varible|filter }} filter {% tag var1

    var2 %} inline  tag
  172. Filters  y  Tags {{ varible|filter }} filter {% tag var1

    var2 %} inline  tag {% tag var1 %} ... {% endtag %} block  tag
  173. Templates:  tags  {%  %}

  174. Templates:  tags  {%  %} {% comment %} Bu! {% endcomment

    %} comment
  175. Templates:  tags  {%  %} {% comment %} Bu! {% endcomment

    %} comment for {% for elemento in lista %} <li>{{ elemento }}<li> {% endfor %}
  176. 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
  177. Templates:  tags  {%  %}

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

    %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% endfor %}
  179. Templates:  tags  {%  %} cycle {% for elemento in lista

    %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% endfor %} include {% include "foo/bar.html" %}
  180. 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 %}
  181. 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 %}
  182.   Tarea:  Tags a) UHlizar  tags  para  que  el  Hmeline

     se   muestre  con  el  siguiente  formato: • <username>:  <tweet>  <Hmestamp> • <username>:  <tweet>  <Hmestamp> • ...
  183.   Tarea:  Tags  avanzados a) Hacer  que  el  Hmeline  muestre

     el   mensaje  “No  hay  tweets.”  si  el   diccionario  recibido  está  vacío.
  184. 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
  185. Templates:  Filters

  186. Templates:  Filters {'username': 'Juan es majo'} {{ username|length }} length

    12
  187. Templates:  Filters {'username': 'Juan es majo'} {{ username|length }} length

    12 {{ username|cut }} cut Juanesmajo
  188. Templates:  Filters {'username': 'Juan es majo'} {{ username|length }} length

    12 {{ username|cut }} cut Juanesmajo {{ username|slugify }} slugify juan-es-majo
  189. Templates:  Filters {'username': 'Juan es majo'} {{ username|length }} length

    12 {{ username|cut }} cut Juanesmajo {{ username|slugify }} slugify juan-es-majo {{ username|wordcount }} wordcount 3
  190. 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
  191. 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
  192. Templates:  Filters

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

    username|striptags }} striptags Juan es majo guapo y listo
  194. 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> ...
  195. 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>
  196. Templates:  Filters

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

    <a href=”http://www.djangoproject.com”> http://www.djangoproject.com </a>
  198. 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>
  199. Templates:  Filters {'lista': ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]}

  200. 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>
  201. Templates:  Filters

  202. Templates:  Filters {'value': 123456789} {{ value|add:”1” }} add 123456790

  203. Templates:  Filters {'value': 123456789} {{ value|add:”1” }} add 123456790 {{

    value|filesizeformat }} filesizeformat 117.7MB
  204. 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
  205. 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
  206. 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
  207. Tarea:  Filters a) Añadir  a  cada  tweet  del  Hmeline  el

      Hempo  transcurrido: • <username>:  <tweet> <n>  seconds  ago • <username>:  <tweet> <n>  minutes  ago • ...
  208. Tarea:  Filters b)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”  
  209. Tarea:  Filters c) Conseguir  que  todas  las  urls  que  

    aparezcan  en  los  tweets  se  conviertan   en  enlaces  <a  href=...  />  de  HTML.
  210. 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 %}
  211. Tarea:  Herencia  de  templates a) 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
  212. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  213. Modelos

  214. ¿SQL?

  215. 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})
  216. 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}) 1 2 3 4 5 6
  217. 12  lineas  de  Python...  ¬_¬

  218. ORM  (Object-­‐RelaHonal  mapping)

  219. ORM  (Object-­‐RelaHonal  mapping)

  220. Ejemplo  ORM def book_list(request): names = Books.objects.all().order_by('name') return render(request, 'book_list.html',

    {'names':names})
  221. Ejemplo  ORM def book_list(request): names = Books.objects.all().order_by('name') return render(request, 'book_list.html',

    {'names':names}) 1 2
  222. Fucking  Ninjas!

  223. Modelo from 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)  
  224. Modelo from 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)  
  225. Fucking  Awesome  Ninjas!

  226. 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
  227. 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
  228. 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
  229. 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
  230. ¿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;
  231. ¿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;
  232. ¿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
  233. Configurar  seyngs.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.', 'NAME':

    '', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } } 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
  234. Configurar  seyngs.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.', 'NAME':

    '', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } } 1 2 3 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
  235. 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
  236. 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
  237. Nuestro  primer  modelo a)Crear  modelo  Tweet b)Configurar  sesngs.py c) Ver

     el  SQL  generado  con  sqlall
  238. syncdb $ python manage.py syncdb Creating table auth_permission Creating table

    auth_group Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating 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): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model
  239. syncdb $ python manage.py syncdb Creating table auth_permission Creating table

    auth_group Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating 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): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model django.contrib.auth
  240. ¿Cuantos  sistemas  de  AutenHcación  habéis  programado?

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

  242. contrib.auth  puede  ser  el  úlHmo  :D

  243. syncdb $ python manage.py syncdb Creating table auth_permission Creating table

    auth_group Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating 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): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model website.tweet
  244. syncdb $ python manage.py syncdb Creating table auth_permission Creating table

    auth_group Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating 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): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model django.contrib.auth
  245. BD  Lista  para  usarse

  246. BD  Lista  para  usarse

  247. Nuestro  primer  modelo a)Hacer  syncdb

  248. None
  249. Previo:  Clases  del  ORM ts = Publisher.objects.all() Model Manager QuerySet

  250. Previo:  __unicode__()

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

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

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

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

    Publisher.objects.all() [<Publisher: Publisher object>]
  255. Previo:  __unicode__() class Publisher(models.Model): ... def __unicode__(self): return self.name >>>

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

  257. 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()
  258. 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)
  259. UPDATE

  260. UPDATE >>> ... >>> p.id 52 >>> p.name = 'Apress

    Publishing' >>> p.save() o.save() 1
  261. UPDATE >>> Publisher.objects.all().update(country='USA') 2 >>> ... >>> p.id 52 >>>

    p.name = 'Apress Publishing' >>> p.save() o.save() queryset.update(...) 1 n
  262. DELETE

  263. DELETE >>> ... >>> p.id 52 >>> p.delete() o.delete() 1

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

    p.id 52 >>> p.delete() o.delete() queryset.delete() 1 n
  265. SELECT  de  1  resultado

  266. SELECT  de  1  resultado >>> Publisher.objects.get(name="Apress") <Publisher: Apress> .get(...)

  267. 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.
  268. 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.
  269. SELECT  de  N  resultados

  270. SELECT  de  N  resultados >>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>]

    .all()
  271. 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(...)
  272. 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(...)
  273. 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!
  274. get(),  filter()  y  exclude()

  275. get(),  filter()  y  exclude() Modelo.objects.filter(campo1="valor1", campo2="valor2") Los  parámetros  pueden  indicar

     mucho  más  que  igualdad  (=)
  276. 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
  277. ORDER  BY

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

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

    Publisher.objects.order_by("-name") [<Publisher: O'Reilly>, <Publisher: Apress>]
  280. 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:
  281. 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!
  282. Slicing

  283. 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>]
  284. 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
  285. 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
  286. Related  Objects

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

    ... 1 1
  288. Related  Objects OneToOneField 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
  289. Related  Objects OneToOneField 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
  290. Related  Objects

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

    ForeignKeyField(Blog) 1 n
  292. Related  Objects ForeignKeyField 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
  293. Related  Objects

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

    ... n m
  295. Related  Objects ManyToManyField 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
  296. Related  Objects

  297. Related  Objects En  todas  ellas  podemos  renombrar  el  puntero  inverso

    class Blog(models.Model): ... class Post(models.Model): blog = ForeignKeyField(Blog, related_name='posts') 1 n
  298. Related  Objects En  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
  299. Related  Objects En  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
  300. Y  la  guinda  final:  ¡Todo  es  LAZY!

  301. Laziness

  302. 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'):
  303. Usando  el  ORM a)Insertar  varios  Tweets  desde  la  shell. b)Modificar

     views.timeline  para  que   uHlice  los  Tweets  reales  de  la  BD.
  304. 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
  305. Profiles

  306. 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.
  307. Profile models.py

  308. 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.
  309. Profile •Donde  tengamos  el  User  tendremos  el  Profile. •Donde  tengamos

     el  Profile,  tendremos  el  User.
  310. 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.
  311. 1  User  =  1  Profile  ¿Cuándo  se  crea  un  User?

  312. 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/
  313. Signals

  314. Signals def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) from

    django.db.models.signals import post_save post_save.connect(create_user_profile, sender=User) 1 2 3 Puede  estar  en  cualquier  app  de  nuestro  proyecto. Se  recomienda  models.py
  315. Users  en  dwiier a)Crear  el  modelo  Profile b)Crear  signal  para

     agregar  un   objeto  Profile  a  cada  objeto   User  creado. c) Eliminar  BD. d)Hacer  syncdb
  316. Followers

  317. Profile models.py

  318. Profile class 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
  319. Users  en  dwiier a)Añadir  ManyToMany  para  los  followers. b)Eliminar  BD.

    c) Hacer  syncdb
  320. 1,2,3  Borrar  la  BD....  1,2,3...  Borrar  la  BD

  321. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  322. CRUD:  Create,  Retrieve,  Update  &  Delete

  323. django.contrib.admin 1 2 3

  324. django.contrib.admin 1 2 3

  325. django.contrib.admin 1

  326. 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
  327. 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
  328. Django  admin:  Instalación INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites',

    ... ) senngs.py
  329. Django  admin:  Instalación INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites',

    'django.contrib.admin', ... ) senngs.py 1
  330. Actualizando  la  BD

  331. Actualizando  la  BD $ python manage.py syncdb Creating table django_admin_log

    Installing index for admin.LogEntry model Admin  lista  para  usar
  332. ¿Y  nuestra  app? ?

  333. ¿Y  nuestra  app?

  334. 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)
  335. Instalar  Admin a)Configurar  urls.py b)Configurar  sesngs.py c) Hacer  syncdb

  336. Instalar  Admin d)Comprobar  que  no  están  Tweet  y  Profile e)Añadir

     admin.py f) Probar  Administración.
  337. Fixtures

  338. 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:
  339. 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 ...>
  340. 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  iniHal_data  y  están  dentro  de  la  carpeta  fixtures   de  la  app,  se  cargan  al  ahcer  el  syncdb.
  341. Tarea:  Avance  en  dwiier a)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
  342. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  343. Formularios

  344. Clases  involucradas

  345. Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput CheckboxInput

    <input type='text'...> <input type='checkbox'...>
  346. Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput CheckboxInput

    <input type='text'...> <input type='checkbox'...> Field Lógica  de  un  campo,  asociado  a  un  Widget EmailField IPAddressField widget, initial, error, ...
  347. Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput CheckboxInput

    <input type='text'...> <input type='checkbox'...> Field Lógica  de  un  campo,  asociado  a  un  Widget EmailField IPAddressField widget, initial, error, ... Form Conjunto  de  Fields  de  un  formulario ContactForm [nombre, email, telefono, mensaje, ...]
  348. Fields

  349. 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
  350. 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
  351. 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
  352. 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
  353. 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
  354. 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
  355. 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
  356. 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
  357. 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>:
  358. 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>:
  359. 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:
  360. Forms  a  parHr  de  Models:  El  COLMO  del  DRY

  361. Forms  a  par/r  de  Models from 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
  362. 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).
  363. Tarea:  Avance  en  dwiier a)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
  364. Índice 1.Python a. Introducción b.Tipos  de  datos c. Operadores d.Usos

     frecuentes e. Estructuras f. Sentencias g. Ejercicio 2.Django a. Introducción b.URLs  y  Vistas c. Templates d.Modelo e. Administración f. Formularios g. Magia  avanzada Proyecto
  365. Magia  avanzada

  366. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  367. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  368. 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!
  369. 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!
  370. Views  avanzadas En  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'), )
  371. Views  avanzadas En  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'), )
  372. Views  avanzadas ¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps?

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

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

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

  376. ROSA

  377. NUNCA ROSA

  378. NUNCA INFRAVALORÉIS ROSA

  379. NUNCA INFRAVALORÉIS EL  PODER ROSA

  380. NUNCA INFRAVALORÉIS EL  PODER DE  UN   PONY ROSA

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

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

  383. Views  avanzadas Generic  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
  384. 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
  385. 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
  386. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  387. Context  Processors ! ! ! !

  388. Context  Processors ¿Context  Processors?  Son  funciones. • Reciben  un  HFpRequest()

     como  único  parámetro. • Devuelven  un  diccionario  para  ser  usado  como  Context().
  389. Context  Processors ¿Context  Processors?  Son  funciones. def ip_address_processor(request): return {'ip_address':

    request.META['REMOTE_ADDR']} • Reciben  un  HFpRequest()  como  único  parámetro. • Devuelven  un  diccionario  para  ser  usado  como  Context().
  390. Context  Processors ¿Context  Processors?  Son  funciones. def ip_address_processor(request): return {'ip_address':

    request.META['REMOTE_ADDR']} • Reciben  un  HFpRequest()  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", )
  391. 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)
  392. 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()
  393. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  394. Template  Library Nos  permite  extender  el  sistema  de  templates  

    de  Django  con  Filters  y  Tags  propios
  395. Template  Library Nos  permite  extender  el  sistema  de  templates  

    de  Django  con  Filters  y  Tags  propios Uso {% load milibreria %} ... {{ variable|mifiltro:"param" }} ... {% mitag param1 param2 %}
  396. Template  Library Nos  permite  extender  el  sistema  de  templates  

    de  Django  con  Filters  y  Tags  propios Uso {% load milibreria %} ... {{ variable|mifiltro:"param" }} ... {% mitag param1 param2 %} Creación
  397. Custom  Filters Un  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.
  398. Custom  Filters Un  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
  399. Custom  Filters Un  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, '')
  400. Python   2.4  se  hizo   sexy Custom  Filters Un

     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, '')
  401. 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.
  402. Custom  Tags El  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
  403. SimpleTags Ejemplo:  Devolver  la  hora  actual  formateada. {% current_time "%Y-%m-%d

    %I:%M %p" %}
  404. SimpleTags Ejemplo:  Devolver  la  hora  actual  formateada. {% current_time "%Y-%m-%d

    %I:%M %p" %} from django import template register = template.Library() @register.simple_tag def current_time(format): try: return datetime.datetime.now().strftime(str(format)) except UnicodeEncodeError: return ''
  405. InclusionTags Ejemplo:  Mostar  anuncios  si  el  usuario  no  es  premium.

    {% show_adverts user %} {% for advert in adverts %} <img src='{{ advert.image }}' /> {% endfor %} adverts.html milibreria.py
  406. InclusionTags Ejemplo:  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
  407. 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
  408. 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=).
  409. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  410. Middleware Nos  permite  escribir  funcionalidad  reu*lizable   que  se  inserta

     en  el  flujo  de  ejecución  de  Django
  411. Middleware class 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.""" # ...
  412. Middleware Tenemos  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', )
  413. Middleware 1. 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  Middleware 1. Si  la  vista  cumple  un  patrón  (User  no  logeado,...)   cacheamos  la  página. 4.  etc...
  414. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  415. 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
  416. Internacionalización • ¿Cómo  indicar  qué  strings  deben  ser  traducidos? •

    GesHón  cómoda  de  singulares  y  plurales
  417. 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
  418. 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
  419. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  420. 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):
  421. 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
  422. caching from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request):

    ... views
  423. 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
  424. caching low  level

  425. caching low  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 •  ...
  426. memcached  DEMO

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

  428. ¿y  para  500k  Usuarios?

  429. ¿y  para  2Millones?

  430. ¿y  para  ++10Millones?

  431. ¿y  para  ++10Millones?

  432. redis

  433. redis •  La  misma  filosoya  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.
  434. redis

  435. 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
  436. 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!
  437. redis  DEMO

  438. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  439. Deploying  Django 1. hip://virtualenv.openplans.org/ 2. hip://pip.openplans.org/

  440. Deploying  Django Virtualenv  +  PIP   1. hip://virtualenv.openplans.org/ 2. hip://pip.openplans.org/

  441. 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...
  442. 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
  443. 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
  444. PIP •Gestor  de  paquetes  del  siglo  21  :D •Permite  especificar

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

     un  fichero  de  REQUIREMENTS  con  un  listado  de   paquetes  a  instalar. Django==1.4 psycopg2 feedparser==4.1 stripogram==1.5 GChartWrapper==0.8 pip install -E mi_entorno -r REQUIREMENTS
  446. Nuestro  primer  Virtualenv  +  PIP a)Crear  un  entorno  virtual b)Instalar

     Django==1.0 c) Probar  django.VERSION
  447. El  Stack

  448. 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. •  hFp://gunicorn.org/ •  Servidor  Web  WSGI  implementado  en  Python •  Facilidades  de  puesta  en  marcha  de  proyectos  django •  Fácilmente  configurable  usando  nginx •  hFp://nginx.org/
  449. nginx  :80 gunicorn Django WSGI  Server Frontend Deploy sencillo worker

     1 worker  2 worker  n
  450. 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 Deploy no  tan  sencillo
  451. Fabric

  452. Repe**on  leads  to  boredom, boredom  to  horrifying  mistakes, horrifying  mistakes

     to  God-­‐I-­‐wish-­‐I-­‐was-­‐s*ll-­‐bored. “
  453. $ fab deploy -R test

  454. $ fab deploy -R www

  455. Magia  avanzada 1. Views  avanzadas 2. Context  Processors 3. Custom

     Template  Filters  &  Tags 4. Middleware 5. Internacionalización 6. Caching 7. Despliegue 8. Apps  recomendadas
  456. Apps

  457. django-­‐south

  458. 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! hFp://south.aeracode.org/
  459. 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
  460. django-­‐south hFp://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
  461. django-­‐haystack  h@p://haystacksearch.org

  462. 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
  463. django-­‐registra/on  h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

  464. 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/
  465. django-­‐registra/on  h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

  466. 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/
  467. django-­‐socialregistra/on  h@p://github.com/flashingpumpkin/django-­‐socialregistra/on

  468. django-­‐socialregistra/on •Configuración  sencilla •Auten*cación  con: •twiFer,  facebook,  oauth,  openid •Integración

     perfecta  con  contrib.auth  h@p://github.com/flashingpumpkin/django-­‐socialregistra/on
  469. django-­‐debug-­‐toolbar  h@p://github.com/robhudson/django-­‐debug-­‐toolbar

  470. Celery  h@p://celeryproject.org

  471. •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
  472. from celery.decorators import task @task def add(x, y): return x

    + y >>> result = add.delay(4, 4) >>> result.wait() # wait for and return the result 8 Celery  h@p://celeryproject.org
  473. from celery.decorators import task @task def add(x, y): return x

    + y >>> result = add.delay(4, 4) >>> result.wait() # wait for and return the result 8 • 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
  474. dajaxproject.com

  475. •  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
  476. 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
  477. Ejemplo from django.utils import simplejson from dajaxice.decorators import dajaxice_register @dajaxice_register

    def my_example(request): return simplejson.dumps({'message':'Hello World'})
  478. Ejemplo from django.utils import simplejson from dajaxice.decorators import dajaxice_register @dajaxice_register

    def my_example(request): return simplejson.dumps({'message':'Hello World'}) Si. es una funcion que retorna json.
  479. Ejemplo function on_whatever(){ Dajaxice.example.my_example(my_js_callback); }

  480. Ejemplo function on_whatever(){ Dajaxice.example.my_example(my_js_callback); } app function name callback

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

  482. Ejemplo function my_js_callback(data){ alert(data.message); } callback your stuff

  483. •  Manipular  el  DOM  usando  Python. •  Sin  necesidad  de

     conocer  JS  en  profundidad. •  Soporta  Frameworks  como Obje/vos  dajax
  484. 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()
  485. 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
  486. Ejemplo function on_whatever(){ Dajaxice.app.assign_test(Dajax.process); }

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

  488. DEMO

  489. django-­‐piston  h@p://bitbucket.org/jespern/django-­‐piston/wiki/Home/

  490. django-­‐piston •  Framework  para  crear  APIs  RESTful •  Muy  fácil

     instalación •  Serialización  a: •JSON,  YAML,  Python  Pyckle,  XML  ... •OAuth  h@p://bitbucket.org/jespern/django-­‐piston/wiki/Home/
  491. Sentry    -­‐  getsentry.com  h@p://getsentry.com

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

  493. 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/
  494. django-­‐command-­‐extensions

  495. django-­‐command-­‐extensions

  496. django-­‐command-­‐extensions

  497. django-­‐command-­‐extensions

  498. Alterna/vas  h@p://flask.pocoo.org  h@p://tornadoweb.org

  499.  h@p://flask.pocoo.org from flask import Flask app = 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/
  500. import tornado.ioloop import 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
  501. Sublime  Text  2  h@p://www.sublimetext.com/2

  502. Pycharm  h@p://www.jetbrains.com/pycharm

  503. La  punta  del  iceberg

  504.  h@p://www.djangobook.com

  505. How  to  ...  using  Django?