Desarrollo web ágil con Python y Django

April 5, 2018 | Author: Anonymous | Category: Technology
Report this link


Description

1. Desarrollo  web  ágil  con  Python  y  DjangoJorge  Bas7da  PérezJaime  Irurzun  Graña   [email protected]@gmail.com @jorgebas7da @jaimeirurzun 2. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 3. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 4. • LegibleSintaxis  intuiHva  y  estricta• Produc/voEntre  1/3  y  1/5  más  conciso  que  Java  o  C++• Portable GNU/Linux,  Windows,  Mac  OS  X,  ...• ExtensoStandard  Library,  Third  parHes• Integrable C,  C++,  Java,  .NET,  COM,  WS,  CORBA,  ...• ...  y  Diver/do 5. Instalación $ sudo apt-get install pythonhttp://www.python.org/download/Snow  Leopard  incluye  las  versiones  2.5.4  y  2.6.1 6. El  Intérprete 7. El  IntérpreteModo  Batchholamundo.py$ python holamundo.py#!/usr/bin/env python hola mundo!print "hola mundo!" $ 8. El  Intérprete Modo  Batch holamundo.py$ python holamundo.py#!/usr/bin/env python hola mundo!print "hola mundo!" $ Modo  Interac7vo$ pythonPython 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)[GCC 4.4.3] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> print "hola mundo!"hola mundo! 9. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 10. Tipos  de  datosobject +  info:  hMp://docs.python.org/library/stdtypes.html 11. Tipos  de  datosint 1234 long 35Lfloat3.1415object +  info:  hMp://docs.python.org/library/stdtypes.html 12. Tipos  de  datosint 1234 long 35Lfloat3.1415 bool True Falseobject +  info:  hMp://docs.python.org/library/stdtypes.html 13. Tipos  de  datosint 1234 long 35Lfloat3.1415 bool True Falsestr spam"guidos""""n lines"""object +  info:  hMp://docs.python.org/library/stdtypes.html 14. Tipos  de  datosint 1234 long 35Lfloat3.1415 bool True Falsestr spam"guidos""""n lines"""objectlist[1, [2, three], 4] +  info:  hMp://docs.python.org/library/stdtypes.html 15. Tipos  de  datosint 1234 long 35Lfloat3.1415 bool True Falsestr spam"guidos""""n lines"""objectlist[1, [2, three], 4] dict {food: spam, taste: yum} +  info:  hMp://docs.python.org/library/stdtypes.html 16. Tipos  de  datos int 1234 long 35Lfloat3.1415 boolTrue False str spam"guidos""""n lines"""object list[1, [2, three], 4]dict {food: spam, taste: yum} tuple (1, spam, 4, U)+  info:  hMp://docs.python.org/library/stdtypes.html 17. Tipos  de  datoso  ¡T i p ad mi co! int 1234 long 35Lfloat d iná3.1415 boolTrue False str spam"guidos""""n lines"""object list[1, [2, three], 4]dict {food: spam, taste: yum} tuple (1, spam, 4, U)+  info:  hMp://docs.python.org/library/stdtypes.html 18. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 19. Operadores+  info:  hMp://docs.python.org/library/operator.html 20. Operadoresa + b a - ba * b a / bnuméricosa % b-a+aa ** b +  info:  hMp://docs.python.org/library/operator.html 21. Operadoresa + b a - ba * b a / bnuméricosa % b-a+aa ** b a < ba bcomparadores a >= b a == b a != b +  info:  hMp://docs.python.org/library/operator.html 22. Operadoresa + b a - ba * ba / bnuméricosa % b-a+a a ** b a < ba bcomparadores a >= b a == b a != b lógicosa or b a and bnot a +  info:  hMp://docs.python.org/library/operator.html 23. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 24. Usos  frecuentes:  list 25. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1 26. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1>>> 2 in numsTrue 27. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1>>> 2 in numsTrue>>> nums.append(4)>>> print nums[1, 2, 3, 4] 28. Usos  frecuentes:  list>>> nums = [1, 2, 3]>>> nums[0]1>>> 2 in numsTrue>>> nums.append(4)>>> print nums[1, 2, 3, 4]>>> len(nums)4 29. Usos  frecuentes:  str 30. Usos  frecuentes:  str>>> "Python mola"[1:4]yth 31. Usos  frecuentes:  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7 32. Usos  frecuentes:  str>>> "Python mola"[1:4]yth>>> "Python mola".find("mola")7>>> "Python mola".replace("Python", "PHP no")PHP no mola 33. 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] 34. 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" 35. Usos  frecuentes:  dict 36. Usos  frecuentes:  dict>>> user = {nick: neo, age: 24}>>> user.keys()[nick, age]>>> user.values()[neo, 24] 37. Usos  frecuentes:  dict>>> user = {nick: neo, age: 24}>>> user.keys()[nick, age]>>> user.values()[neo, 24]>>> user[age] >>> user.get(age, 20)2424 38. Usos  frecuentes:  dict>>> user = {nick: neo, age: 24}>>> user.keys()[nick, age]>>> user.values()[neo, 24]>>> user[age] >>> user.get(age, 20)2424>>> user.has_key(nick)True 39. Usos  frecuentes:  dict>>> user = {nick: neo, age: 24}>>> user.keys()[nick, age]>>> user.values()[neo, 24]>>> user[age] >>> user.get(age, 20)2424>>> user.has_key(nick)True>>> user.update({nick: alatar, age: 25})>>> user{nick: alatar, age: 25} 40. Usos  frecuentes:  str  % 41. Usos  frecuentes:  str  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio 42. Usos  frecuentes:  str  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio>>> "%s sabe %i idiomas" % ("Hycker", 5)Hycker sabe 5 idiomas 43. Usos  frecuentes:  str  %>>> "%s es muy sabio" % "Hycker"Hycker es muy sabio>>> "%s sabe %i idiomas" % ("Hycker", 5)Hycker sabe 5 idiomas>>> t = "%(NOMBRE)s sabe %(IDIOMAS)i idiomas">>> v = {NOMBRE: Hycker, IDIOMAS: 5}>>> t % vHycker sabe 5 idiomas 44. Módulossound/__init__.py1. Un  módulo  es  un  fichero  .pyformats/__init__.pywavread.pywavwrite.py2. Los  módulos  pueden  aiffread.pyaiffwrite.pyauread.py organizarse  en  paquetes.auwrite.py...effects/__init__.py3. Un  paquete  es  una  carpeta  echo.pysurround.pyreverse.pyque  conHene  un  fichero  con  ...filters/__init__.py nombre  __init__.pyequalizer.pyvocoder.pykaraoke.py... 45. Módulossound/ 2__init__.py 1. Un  módulo  es  un  fichero  .pyformats/__init__.pywavread.pywavwrite.py 2. Los  módulos  pueden   1 aiffread.pyaiffwrite.pyauread.pyorganizarse  en  paquetes.auwrite.py...effects/__init__.py 3 3. Un  paquete  es  una  carpeta  echo.pysurround.pyreverse.py que  conHene  un  fichero  con  ...filters/__init__.pynombre  __init__.pyequalizer.pyvocoder.pykaraoke.py... 46. Módulos import math ¿Dónde  los  busca  Python?En  la  lista  de  directorios  que  conHene  la  lista  sys.path: 1. El  directorio  actual:./ 2. El  directorio  site-packages  de  nuestro  Python:/usr/local/lib/python2.6/site-packages 3. Los  directorios  apuntados  por  PYTHONPATH:$ env | grep PYTHONPATH 4. El  directorio  de  la  instalación  de  Python:/usr/lib/python2.6/ 47. Módulossound/ import sound.effects.echo__init__.pysound.effects.echo.echofilter(...)formats/__init__.pywavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects/__init__.pyecho.pysurround.pyreverse.py...filters/__init__.pyequalizer.pyvocoder.pykaraoke.py... 48. Módulossound/ import sound.effects.echo__init__.pysound.effects.echo.echofilter(...)formats/__init__.pywavread.pywavwrite.pyfrom sound.effects import echoaiffread.pyecho.echofilter(...)aiffwrite.pyauread.pyauwrite.py...effects/__init__.pyecho.pysurround.pyreverse.py...filters/__init__.pyequalizer.pyvocoder.pykaraoke.py... 49. Módulossound/ import sound.effects.echo__init__.pysound.effects.echo.echofilter(...)formats/__init__.pywavread.pywavwrite.pyfrom sound.effects import echoaiffread.pyecho.echofilter(...)aiffwrite.pyauread.pyauwrite.py... from sound.effects.echo import echofiltereffects/ echofilter(...)__init__.pyecho.pysurround.pyreverse.py...filters/__init__.pyequalizer.pyvocoder.pykaraoke.py... 50. Módulossound/ import sound.effects.echo__init__.pysound.effects.echo.echofilter(...)formats/__init__.pywavread.pywavwrite.pyfrom sound.effects import echoaiffread.pyecho.echofilter(...)aiffwrite.pyauread.pyauwrite.py... from sound.effects.echo import echofiltereffects/ echofilter(...)__init__.pyecho.pysurround.pyreverse.py...from sound.effects.echo import *filters/ echofilter(...)__init__.pyequalizer.pyvocoder.pykaraoke.py... 51. Módulossound/ import sound.effects.echo__init__.pysound.effects.echo.echofilter(...)formats/__init__.pywavread.pywavwrite.pyfrom sound.effects import echoaiffread.pyecho.echofilter(...)aiffwrite.pyauread.pyauwrite.py... from sound.effects.echo import echofiltereffects/ echofilter(...)__init__.pyecho.pysurround.pyreverse.py...from sound.effects.echo import *filters/ echofilter(...)__init__.pyequalizer.pyvocoder.pykaraoke.py from sound.effects import echo as rev...rev.echofilter(...) 52. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 53. Estructuras {} 54. Estructuras {} 55. Identación>>> from __future__ import braces File "", line 1 SyntaxError: not a chance 56. Identación>>> from __future__ import braces File "", line 1 SyntaxError: not a chancePEP 8 4  Espacios  para  indicar  la  identación 57. ¿PEP  8? PEP 8•  Guido  van  Rossum  (2001)•  Recomendaciones  de  esHlo•  “Readability  counts”•  “Code  is  read  much  more  ofen  than  it  is  wrigen.”•  Muy  recomendable  importante  seguirlo. hMp://www.python.org/dev/peps/pep-­‐0008/ 58. Funcionesdef my_first_function(p1, p2):return "Hello World!" 59. Funciones1 def my_first_function(p1, p2):return "Hello World!" 60. Funciones21 def my_first_function(p1, p2):return "Hello World!" 61. Funciones21 def my_first_function(p1, p2):3 return "Hello World!" 62. Funciones 21 def my_first_function(p1, p2):3 return "Hello World!" PEP 8 Recomendaciones:•  Minúsculas•  Palabras  separadas  por  _•  Evitar  camelCase 63. Conversión  de  /pos +info:  hMp://docs.python.org/library/func7ons.html 64. Conversión  de  /pos>>> int(1.3)1 +info:  hMp://docs.python.org/library/func7ons.html 65. Conversión  de  /pos>>> int(1.3)1>>> str(2)2 +info:  hMp://docs.python.org/library/func7ons.html 66. Conversión  de  /pos>>> int(1.3)1>>> str(2)2>>> float(1)1.0 +info:  hMp://docs.python.org/library/func7ons.html 67. Conversión  de  /pos>>> int(1.3)1 >>> tuple([1,2,3]) (1, 2, 3)>>> str(2)2>>> float(1)1.0 +info:  hMp://docs.python.org/library/func7ons.html 68. Conversión  de  /pos>>> int(1.3)1 >>> tuple([1,2,3]) (1, 2, 3)>>> str(2)2 >>> list((1,2,3)) [1, 2, 3]>>> float(1)1.0 +info:  hMp://docs.python.org/library/func7ons.html 69. Funciones  comunes +info:  hMp://docs.python.org/library/func7ons.html 70. Funciones  comunes>>> len("Python Mola")11>>> len([1,2,3,4])4+info:  hMp://docs.python.org/library/func7ons.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] +info:  hMp://docs.python.org/library/func7ons.html 72. Funciones  comunes >>> type(True)>>> len("Python Mola") 11 >>> type("Python Mola")>>> 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] +info:  hMp://docs.python.org/library/func7ons.html 73. Funciones  comunes >>> type(True)>>> len("Python Mola") 11 >>> type("Python Mola")>>> len([1,2,3,4]) 4>>> range(5) >>> sum([0,1,2,3,4])[0, 1, 2, 3, 4]10>>> range(1,7) >>> sum(range(5))[1, 2, 3, 4, 5, 6] 10>>> range(1,7,2)[1, 3, 5] Y  un  muy  largo  etc... +info:  hMp://docs.python.org/library/func7ons.html 74. Funciones  interesantes Son  sólo  un  ejemplo...+info:  hMp://docs.python.org/library/func7ons.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... +info:  hMp://docs.python.org/library/func7ons.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... +info:  hMp://docs.python.org/library/func7ons.html 77. Funciones  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> round(1.2345,2)>>> zip(a,b) 1.23[(1, 4), (2, 5), (3, 6)]>>> sorted([5,1,3,4,2])[1, 2, 3, 4, 5]Son  sólo  un  ejemplo... +info:  hMp://docs.python.org/library/func7ons.html 78. Funciones  interesantes>>> a = [1,2,3]>>> b = [4,5,6]>>> round(1.2345,2)>>> zip(a,b) 1.23[(1, 4), (2, 5), (3, 6)]>>> sorted([5,1,3,4,2]) >>> map(str,[1,2,3,4,5])[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]Son  sólo  un  ejemplo... +info:  hMp://docs.python.org/library/func7ons.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 stringReturn those items of sequence for which function(item) is true. Iffunction is None, return the items that are true. If sequence is a tupleor string, return the same type, else return a list.(END) 82. Clasesclass Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % self.name s = Student("Jorge", 24) 83. Clases1class Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % self.name s = Student("Jorge", 24) 84. Clases12class Student(object):def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % self.name s = Student("Jorge", 24) 85. Clases12class Student(object):3 def __init__(self, name, age):self.name = nameself.age = agedef hello(self):return My name is %s % self.name s = Student("Jorge", 24) 86. Clases12class Student(object):3 def __init__(self, name, age):4 self.name = nameself.age = agedef hello(self):return My name is %s % self.name s = Student("Jorge", 24) 87. Clases12class Student(object):3 def __init__(self, name, age):4 self.name = nameself.age = agedef hello(self): 5return My name is %s % self.name s = Student("Jorge", 24) 88. Clases12class Student(object):3 def __init__(self, name, age):4 self.name = nameself.age = agedef hello(self): 5return My name is %s % self.name s = Student("Jorge", 24) PEP 8Recomendaciones: •  CamelCase 89. El  operador  ()• Es  importante  diferenciar:funcion      vs      funcion()Clase              vs        Clase()• El  operador  ()  permite:• Invocar  funciones:resultado = funcion()• Instanciar  clases:objeto = Clase("param1") 90. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 91. Sentencias:  if-­‐else$name = "Jon"; name = "Jon"if($name == "Jon"){if name == "Jon":$name = "Jon Rocks!";name = "Jon Rocks!"}elif name == "Mary":elseif($name == "Mary"){ name = "Hello Mary"$name = "Hello Mary";else:}name = "Who are you?"else{$name = "Who are you?"} 92. Sentencias:  while $count = 0; while ($count < 5) { echo "Number ".$count; $count+=1; } count = 0 while count < 5: print "Number %i" % count count+=1 93. Sentencias:  forfor ($i=0; $i < 5; $i++) {echo "Number ".$count;}for i in range(4):print "Number %i" % count 94. Sentencias:  try-­‐except try { $result = 3 / 0; } catch (Exception $e) { echo "Division by Zero" } try: result = 3 / 0 except:print "Division by Zero" 95. Prueba  de  sentencias  en  consola 96. Conclusiones•  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. 97. Conclusiones•  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... 98. Ejemplo  &  Ejercicio 99. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 100. Evolución  de  la  Web Desarrollo  Web1ª  Generación2ª  Generación 3ª  GeneraciónHTMLPHP Django CGIASPRailsJSPSymfony ...... 101. Frameworks  web 102. Django:  Qué  y  dónde 103. FilosoXa•  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) 104. FilosoXa•  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.” 105. FilosoXa•  Explicit  is  beger  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.hMp://docs.djangoproject.com/en/dev/misc/design-­‐philosophies/ 106. La  comunidad 107. La  comunidad• django-­‐users18.000  miembros 108. La  comunidad• django-­‐users18.000  miembros• django-­‐developers5.900  miembros 109. La  comunidad• django-­‐users18.000  miembros• django-­‐developers5.900  miembros• djangoproject.com500.000  visitas  únicas  mensuales 110. ¿Quién  usa  Django? 111. ¿Quién  usa  Django? etc... 112. 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 113. 2.  Instalación  SGBDConfigurar  un  motor  de  Base  de  Datos:•  Oficiales:   •  Comunidad:  •  PostgreSQL•  Sybase  SQL  Anywhere•  MySQL •  IBM  DB2 •  Microsof  SQL  Server  2005•  Oracle •  Firebird•  SQLite•  ODBC 114. 2.  Instalación  SGBDConfigurar  un  motor  de  Base  de  Datos:•  Oficiales:   •  Comunidad:  •  PostgreSQL•  Sybase  SQL  Anywhere•  MySQL •  IBM  DB2 •  Microsof  SQL  Server  2005•  Oracle •  Firebird•  SQLite•  ODBC 115. 2.  Instalación  SGBD•  Vamos  a  uHlizar  SQLite  por  comodidad•  Desde  Python  2.5  podemos  uHlizar  sqlite    sin  instalar  nada. 116. 2.  Instalación  SGBD•  Vamos  a  uHlizar  SQLite  por  comodidad•  Desde  Python  2.5  podemos  uHlizar  sqlite    sin  instalar  nada. 117. 3.  Instalación  DjangoA:  Paquetes  de  cada  distro • apt-get install python-djangoB:  Official  Release • hMp://www.djangoproject.com/download/ • python setup.py installC:  Trunk • hMp://code.djangoproject.com/svn/django/trunk/ 118. All  Right? 119. All  Right?>>> import django>>> django.VERSION(1, 2, 3, final, 0)>>> import djangoTraceback (most recent call last):File "", line 1, in ImportError: No module named django 120. Bienvenidos  al  mundo  de  Oz 121. Ficheros  y  Carpetas¿Es  Django  tán  simple  y  fácil  de  usar? *  Incluida  la  carpeta  del  proyecto 122. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar?FicherosCarpetas*  Incluida  la  carpeta  del  proyecto 123. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Rails SymfonyFicheros 149 117Carpetas35 29*  Incluida  la  carpeta  del  proyecto 124. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Rails SymfonyFicheros 149 117Carpetas35 29*  Incluida  la  carpeta  del  proyecto 125. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Rails SymfonyDjangoFicheros 149 117 4Carpetas35 291*  Incluida  la  carpeta  del  proyecto 126. Let’s  enjoy 127. Crear  nuestro  proyectode  4  ficheros  ;-­‐) 128. Crear  nuestro  proyectode  4  ficheros  ;-­‐)$ django-admin startproject dwitter 129. Crear  nuestro  proyectode  4  ficheros  ;-­‐)$ django-admin startproject dwitter__init__.py manage.pysettings.pyurls.py 130. Crear  nuestro  proyecto de  4  ficheros  ;-­‐)$ django-admin startproject dwitter __init__.py manage.py settings.pyurls.py -­‐  ¿Esto  es  un  proyecto...  ?      Si  os  ve  mi  jefe... 131. Crear  nuestro  proyecto de  4  ficheros  ;-­‐)$ django-admin startproject dwitter __init__.py manage.py settings.pyurls.py -­‐  ¿Esto  es  un  proyecto...  ?      Si  os  ve  mi  jefe... -­‐  Sí,  disponemos  de  un  proyecto  ‘funcional’  en  django. 132. sesngs.py 133. Arrancar  nuestro  proyectode  4  ficheros  ;-­‐) 134. Arrancar  nuestro  proyectode  4  ficheros  ;-­‐) $ cd dwitter $ python manage.py runserver Validating models... 0 errors found Django version 1.1, using settings dwitter.settings Development server is running at http:// 127.0.0.1:8000/ Quit the server with CONTROL-C. 135. Arrancar  nuestro  proyectode  4  ficheros  ;-­‐) $ cd dwitter $ python manage.py runserver Validating models... 0 errors found Django version 1.1, using settings dwitter.settings Development server is running at http:// 127.0.0.1:8000/ Quit the server with CONTROL-C. 136. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 137. MVC  en  DjangoModelo  =  Model Vista  =  Template Controlador  =  URL+View 138. URLs  y  Vistas• El  fichero  urls.py  actúa  como  puerta  de  entrada  para  las   pe7ciones  HTTP• Se  definen  URLs  elegantes  mediante  expresiones  regulares   que  redirigen  a  funciones  de  views.py hMp://mysite.com/about/ urls.py ¿urlpaMerns?html views.py ... 139. URLs  y  Vistas• La  función  de  views.py  recibe  como  parámetros  un  objeto   HhpRequest  y  todos  los  parámetros  de  la  URL  capturados,   teniendo  que  devolver  siempre  un  objeto  HhpResponse HhpRequest(),  ... views.py HhpResponse() 140. URLs  y  Vistas Ejemplo  1:    http://mysite.com/time from django.conf.urls.defaults import * from mysite.views import hora_actual urls.py urlpatterns = patterns(, (r^time/$, hora_actual), ) from django.http import HttpResponse from datetime import datetimeviews.py def hora_actual(request): now = datetime.now() html = "Son las %s." % now return HttpResponse(html) 141. URLs  y  Vistas Ejemplo  2:    http://mysite.com/time/plus/2 from django.conf.urls.defaults import * from mysite.views import dentro_de urls.py urlpatterns = patterns(, (r^time/plus/(d{1,2})/$, dentro_de), ) from django.http import HttpResponse from datetime import datetime, timedelta def dentro_de(request, offset):views.py offset = int(offset) dt = datetime.now() + timedelta(hours=offset) html = "En %i hora(s), serán las %s." % (offset, dt) return HttpResponse(html) 142. URLs  y  Vistas Ejemplo  2:    http://mysite.com/time/plus/2 from django.conf.urls.defaults import * from mysite.views import dentro_de urls.py urlpatterns = patterns(, (r^time/plus/(d{1,2})/$, dentro_de), ) from django.http import HttpResponse from datetime import datetime, timedelta def dentro_de(request, offset):views.py offset = int(offset) dt = datetime.now() + timedelta(hours=offset) html = "En %i hora(s), serán las %s." % (offset, dt) return HttpResponse(html) 143. ¡Recuerda!:  MVC 144. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 145. Templates• Separan  la  lógica  de  presentación  a  una  capa  independiente. • Ficheros  independientes  (.html) • Lenguaje  independiente  (¡para  diseñadores!) 146. Templates • Se  basan  en  dos  7pos  de  objetos:  Template()  y  Context(). • Un  objeto  Template()  con7ene  el  string  de  salida  que  queremos  devolver  en  el  HMpResponse  (normalmente  HTML),  pero  incluyendo  e7quetas  especiales  de  Django. • Un  objeto  Context()  con7ene  un  diccionario  con  los  valores  que  dan  contexto  a  una  plan7lla,  los  que  deben  usarse  para  renderizar  un  objeto  Template().Template:"Bienvenido, {{ user }}.""Bienvenido, alatar." Context:{user: alatar} 147. Templates• Primera  aproximación  al  obje7vo:  Template  +  Context from django.http import HttpResponse from django.template import Template, Context from datetime import datetime PLANTILLA = """ Son las {{ hora }}. """ def hora_actual(request): now = datetime.now() t = Template(PLANTILLA) c = Context({hora: now}) html = t.render(c) return HttpResponse(html) 148. Templates• Segunda  aproximación  al  obje7vo:  open(),  read(),  close()from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()fp = open(/home/django/templates/hora.html)t = Template(fp.read())fp.close()c = Context({hora: now})html = t.render(c)return HttpResponse(html) 149. Templates• Segunda  aproximación  al  obje7vo:  open(),  read(),  close()from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()fp = open(/home/django/templates/hora.html)t = Template(fp.read())fp.close()c = Context({hora: now})html = t.render(c)return HttpResponse(html) 150. Templates• Segunda  aproximación  al  obje7vo:  open(),  read(),  close()from django.http import HttpResponsefrom django.template import Template, Contextfrom datetime import datetimedef hora_actual(request):now = datetime.now()Bo ring   plate  fp = open(/home/django/templates/hora.html) boilert = Template(fp.read())fp.close()code!c = Context({hora: now})html = t.render(c)return HttpResponse(html) 151. Templates• Tercera  aproximación  al  obje7vo:  get_template() TEMPLATE_DIRS = ( sesngs.py /home/django/templates, ) 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) 152. Templates• Tercera  aproximación  al  obje7vo:  get_template() TEMPLATE_DIRS = ( sesngs.py /home/django/templates, ) 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) 153. Templates• Tercera  aproximación  al  obje7vo:  get_template() TEMPLATE_DIRS = ( sesngs.py /home/django/templates, ) 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):S7ll   now = datetime.now() t = get_template(hora.html) c = Context({hora: now}) html = t.render(c)boring... return HttpResponse(html) 154. Templates• Obje7vo  alcanzado:  render_to_response() from django.shortcuts import render_to_response from datetime import datetime def hora_actual(request): now = datetime.now() return render_to_response(hora.html, {hora: now}) 155. Templates• Obje7vo  alcanzado:  render_to_response() from django.shortcuts import render_to_response from datetime import datetime def hora_actual(request): now = datetime.now() return render_to_response(hora.html, {hora: now}) Bori ng...? 156. Templates• Obje7vo  alcanzado:  render_to_response() from django.shortcuts import render_to_response from datetime import datetime def hora_actual(request): now = datetime.now() return render_to_response(hora.html, {hora: now})AWESOME! 157. Templates:  TipTEMPLATE_DIRS = (a) sesngs.py/home/django/templates,) 158. Templates:  TipTEMPLATE_DIRS = (Reusa ble  a) sesngs.py/home/django/templates,)apps? 159. Templates:  TipTEMPLATE_DIRS = (Reusa ble  a) sesngs.py/home/django/templates,)apps?b) Alterna7va  reu7lizable: TEMPLATE_LOADERS = ( django.template.loaders.filesystem.Loader, django.template.loaders.app_directories.Loader, ) • La  carpeta  /templates  es  buscada  dentro  de  cada  app. • Conviene  incluir  una  carpeta  con  el  nombre  de  la  app  por  claridad. return render_to_response(website/index.html) 160. a) Crear  la  app  dwiger.website.b) Incluir  la  app  en  sesngs.py.c) Definir  una  vista  para  la  URL  “/”  que   devuelva  el  texto  “Bienvenidos  a   dwiger”: ‣/ ‣ timeline(request) ¡Empieza  nuestro  primer  proyecto! 161. Tarea  1:  URLs  y  Vistas a) Definir  todas  las  URLs  y  vistas  (vacías)  que  va  a  tener  el  proyecto: ‣ user//status// ‣ tweet_page(request, tweet_id) ‣ user// ‣ user_page(request, username) ‣ users/ ‣ users_list(request) ‣ user//follow/ ‣ follow_user(request, username) ‣ user//unfollow/ ‣ unfollow_user(request, username) 162. Tarea  1:  URLs  y  Vistas b) Implementar  la  vista  timeline()  para  que  renderice  un  Hmeline  de  twiger  en  una  template  index.html  a  parHr  de  datos  hardcodeados  en  un  diccionario. 163. 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 164. FilosoXa  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. 165. Templates:  {{}}Ejemplo templatesHola, {{ username }}. {username: juan}Ejemplo templatesHola, juan. 166. Filters  y  Tags 167. Filters  y  Tags 168. Filters  y  Tagsfilter {{ varible|filter }} 169. Filters  y  Tagsfilter {{ varible|filter }}inline  tag {% tag var1 var2 %} 170. Filters  y  Tagsfilter {{ varible|filter }}inline  tag {% tag var1 var2 %}block  tag{% tag var1 %}...{% endtag %} 171. Templates:  tags  {%  %} 172. Templates:  tags  {%  %}comment {% comment %} Bu! {% endcomment %} 173. Templates:  tags  {%  %}comment {% comment %} Bu! {% endcomment %}for {% for elemento in lista %}{{ elemento }}{% endfor %} 174. Templates:  tags  {%  %}comment{% comment %} Bu! {% endcomment %}for{% for elemento in lista %} {{ elemento }} {% endfor %}if {% if username == "Juan" %} Hola Juan, me gustas!== != >< >= >> Publisher.objects.all()[] 262. Previo:  __unicode__()>>> Publisher.objects.all()[] 263. Previo:  __unicode__()>>> Publisher.objects.all()[] 264. Previo:  __unicode__()>>> Publisher.objects.all()[]class Publisher(models.Model):...def __unicode__(self):return self.name 265. Previo:  __unicode__()>>> Publisher.objects.all()[]class Publisher(models.Model):...def __unicode__(self):return self.name>>> Publisher.objects.all()[] 266. INSERT 267. INSERT o = Model(...)o.save()a) >>> p = Publisher( ... name=Apress, ... address=2855 Telegraph Avenue, ... city=Berkeley, ... state_province=CA, ... country=U.S.A., ... website=http://www.apress.com/) >>> p.save() 268. INSERT o = Model(...)o.save()a) >>> p = Publisher( ... name=Apress, ... address=2855 Telegraph Avenue, ... city=Berkeley, ... state_province=CA, ... country=U.S.A., ... website=http://www.apress.com/) >>> p.save()manager.create(...)b) >>> p = Publisher.objects.create( ... name=OReilly, ... address=10 Fawcett St., ... city=Cambridge, ... state_province=MA, ... country=U.S.A., ... website=http://www.oreilly.com/) 269. UPDATE 270. UPDATE o.save()>>> ...>>> p.id1 52>>> p.name = Apress Publishing>>> p.save() 271. UPDATE o.save()>>> ...>>> p.id1 52>>> p.name = Apress Publishing>>> p.save() queryset.update(...)n >>> Publisher.objects.all().update(country=USA)2 272. DELETE 273. DELETEo.delete()>>> ...>>> p.id1 52>>> p.delete() 274. DELETEo.delete()>>> ...>>> p.id1 52>>> p.delete()queryset.delete()>>> ps = Publisher.objects.all()n >>> ps.delete() 275. SELECT  de  1  resultado 276. SELECT  de  1  resultado .get(...)>>> Publisher.objects.get(name="Apress") 277. SELECT  de  1  resultado .get(...)>>> Publisher.objects.get(name="Apress")>>> Publisher.objects.get(name="Anaya")Traceback (most recent call last):...DoesNotExist: Publisher matching query does not exist. 278. SELECT  de  1  resultado .get(...)>>> Publisher.objects.get(name="Apress")>>> Publisher.objects.get(name="Anaya")Traceback (most recent call last):...DoesNotExist: Publisher matching query does not exist.>>> 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.} 279. SELECT  de  N  resultados 280. SELECT  de  N  resultados .all()>>> Publisher.objects.all()[, ] 281. SELECT  de  N  resultados .all()>>> Publisher.objects.all()[, ].filter(...)>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[] 282. SELECT  de  N  resultados .all()>>> Publisher.objects.all()[, ].filter(...)>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[] .exclude(...)>>> Publisher.objects.exclude(country="U.S.A.", state_province="CA")[] 283. SELECT  de  N  resultadosen  evuelv¡Ds,  no  .all()uerySetQ li stas! >>> Publisher.objects.all() [, ] .filter(...) >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [].exclude(...) >>> Publisher.objects.exclude( country="U.S.A.", state_province="CA") [] 284. get(),  filter()  y  exclude() 285. get(),  filter()  y  exclude() Modelo.objects.filter(campo1="valor1", campo2="valor2")Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=) 286. get(),  filter()  y  exclude() Modelo.objects.filter(campo1="valor1", campo2="valor2") Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=)campo__exact=campo__gt=0 campo__startswith=campo__iexact= campo__gte=0campo__istartswith=campo__contains= campo__lt=0 campo__endswith=campo__icontains=campo__lte=0campo__iendswith=campo__isnull=T|Fcampo__in=[ ,]campo__range=( ,)campo__day=31campo__month=12 campo__year=2010 287. ORDER  BY 288. ORDER  BY.order_by(...)>>> Publisher.objects.order_by("name")[, ] 289. ORDER  BY.order_by(...)>>> Publisher.objects.order_by("name")[, ]>>> Publisher.objects.order_by("-name")[, ] 290. ORDER  BY.order_by(...) >>> Publisher.objects.order_by("name") [, ] >>> Publisher.objects.order_by("-name") [, ]MúlHples  campos:>>> Publisher.objects.order_by("-name", "country")[, ] 291. ORDER  BY ¡También  devu elve  .order_by(...)uer y Sets!Q >>> Publisher.objects.order_by("name") [, ] >>> Publisher.objects.order_by("-name") [, ]MúlHples  campos:>>> Publisher.objects.order_by("-name", "country")[, ] 292. Slicing 293. Slicing [n:m]>>> Publisher.objects.order_by("name")[0]>>> Publisher.objects.order_by("name")[:2][, ]>>> Publisher.objects.order_by("name")[1:2][] 294. Slicing [n:m]>>> Publisher.objects.order_by("name")[0]>>> Publisher.objects.order_by("name")[:2][, ] LIMIT>>> Publisher.objects.order_by("name")[1:2][] 295. Slicing [n:m]>>> Publisher.objects.order_by("name")[0]>>> Publisher.objects.order_by("name")[:2][, ] LIMIT>>> Publisher.objects.order_by("name")[1:2][]O FFSET 296. Related  Objects 297. Related  ObjectsOneToOneField class Coche(models.Model):1motor = OneToOneField(Motor) class Motor(models.Model):1... 298. Related  ObjectsOneToOneFieldclass Coche(models.Model):1 motor = OneToOneField(Motor)class Motor(models.Model):1 ... ¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros>>> c.motor 299. Related  ObjectsOneToOneFieldclass Coche(models.Model):1 motor = OneToOneField(Motor)class Motor(models.Model):1 ... ¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros Gracias  a  Django>>> c.motor >>> m.coche 300. Related  Objects 301. Related  ObjectsForeignKeyFieldclass Blog(models.Model):1 ...class Post(models.Model):n blog = ForeignKeyField(Blog) 302. Related  Objects ForeignKeyField class Blog(models.Model): 1 ... class Post(models.Model): n blog = ForeignKeyField(Blog) ¿Cómo  usamos  la  relación  desde  las  instancias?Gracias  a  nosotros Gracias  a  Django>>> p.blog >>> b.post_set.all()[, ...] 303. Related  Objects 304. Related  ObjectsManyToManyFieldclass Post(models.Model):n tags = ManyToManyField(Tag)class Tag(models.Model):m ... 305. Related  ObjectsManyToManyFieldclass Post(models.Model):n tags = ManyToManyField(Tag)class Tag(models.Model): m... ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django>>> p.tags.add(t1, t2) >>> t.post_set.add(p1, p2)>>> p.tags.all() >>> t.post_set.all()[, ...] [, ...] 306. Related  Objects 307. Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inversoclass Blog(models.Model):1 ...class Post(models.Model):n blog = ForeignKeyField(Blog, related_name=posts) 308. Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inverso class Blog(models.Model):1... class Post(models.Model):nblog = ForeignKeyField(Blog, related_name=posts)Gracias  a  nosotros Gracias  a  Django>>> p.blog >>> b.posts.all()[, ...] 309. Related  ObjectsEn  todas  ellas  podemos  renombrar  el  puntero  inversoclass Blog(models.Model): 1...class Post(models.Model): nblog = ForeignKeyField(Blog, related_name=posts) Gracias  a  nosotrosGracias  a  Django >>> p.blog>>> b.posts.all() [, ...]Cuando  haya  2  relaciones  entre  2  modelos,  será  obligatorio 310. Y  la  guinda  final:  ¡Todo  es  LAZY! 311. Laziness 312. Laziness• Las  consultas  sólo  se  ejecutarán  cuando  realmente  se   necesite  obtener  los  objetos.  En  las  siguientes  situaciones:• Iteraciones for p in Publisher.objects.all():• Slicing Publisher.objects.filter(country=USA)[0]• Serialización [Caché]• repr()[]• len() !!! len(Publisher.objects.all())• list()list(Publisher.objects.all())• bool()if Publisher.objects.filter(country=USA): 313. a) Insertar  varios  Tweets  desde  la  shell.b)Modificar  views.timeline  para  que   uHlice  los  Tweets  reales  de  la  BD.c) Implementar  la  vista  tweet_page()  como   permalink  de  un  tweet: ‣ URL:    user//status/ ‣ View:    tweet_page ‣ Template:    tweet_page.html    (Descargar)d)Lanzar  Http404  si  no  existe  el  tweet_id.e) shortcut!:  get_object_or_404() Usando  el  ORM 314. Profiles 315. 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. 316. Profile models.py 317. Profile models.pyclass Profile(models.Model): user = models.OneToOneField(User, unique=True) 318. Profile models.pyclass Profile(models.Model): user = models.OneToOneField(User, unique=True) bio = models.CharField(blank=True, max_length=200) 319. Profile models.pyclass Profile(models.Model): user = models.OneToOneField(User, unique=True) bio = models.CharField(blank=True, max_length=200) ... 320. Profile models.pyclass Profile(models.Model): user = models.OneToOneField(User, unique=True) bio = models.CharField(blank=True, max_length=200) ... sesngs.pyAUTH_PROFILE_MODULE = "website.Profile" 321. Profile models.py class Profile(models.Model):user = models.OneToOneField(User, unique=True)bio = models.CharField(blank=True, max_length=200)... sesngs.py AUTH_PROFILE_MODULE = "website.Profile"•  Cada  objeto  User  de  django.contrib.auth  dispone  de  un  método  get_profile()  que  nos  permiHrá  acceder  al  Profile. 322. Profile• Donde  tengamos  el  User  tendremos  el  Profile.• Donde  tengamos  el  Profile,  tendremos  el  User. 323. Profile>>> from django.contrib.auth.models import User>>> u = User.objects.get(id=1)>>> type(u)>>> profile = u.get_profile()>>> type(profile)• Donde  tengamos  el  User  tendremos  el  Profile.• Donde  tengamos  el  Profile,  tendremos  el  User. 324. 1  User  =  1  Profile  ¿Cuándo  se  crea  un  User? 325. 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_finishedhMp://docs.djangoproject.com/en/dev/ref/signals/ 326. Signals 327. Signalsdef profile_signal_callback(sender, **kwargs): 1if kwargs.get(created):profile = Profile()profile.user = kwargs.get(instance)profile.save()from django.db.models.signals import post_savepost_save.connect(profile_signal_callback, sender=User,dispatch_uid="users-profilecreation-signal") 328. Signalsdef profile_signal_callback(sender, **kwargs): 1if kwargs.get(created):profile = Profile() 2profile.user = kwargs.get(instance)profile.save()from django.db.models.signals import post_savepost_save.connect(profile_signal_callback, sender=User,dispatch_uid="users-profilecreation-signal") 329. Signalsdef profile_signal_callback(sender, **kwargs): 1if kwargs.get(created):profile = Profile() 2profile.user = kwargs.get(instance)profile.save()from django.db.models.signals import post_save 3post_save.connect(profile_signal_callback, sender=User,dispatch_uid="users-profilecreation-signal") 330. Signalsdef profile_signal_callback(sender, **kwargs): 1if kwargs.get(created):profile = Profile() 2profile.user = kwargs.get(instance)profile.save()from django.db.models.signals import post_save 3post_save.connect(profile_signal_callback, sender=User,4dispatch_uid="users-profilecreation-signal") 331. Signalsdef profile_signal_callback(sender, **kwargs): 1if kwargs.get(created):profile = Profile() 2profile.user = kwargs.get(instance)profile.save()from django.db.models.signals import post_save3post_save.connect(profile_signal_callback, sender=User,4dispatch_uid="users-profilecreation-signal")Puede  estar  en  cualquier  app  de  nuestro  proyecto.Se  recomienda  models.py 332. a) Crear  el  modelo  Profileb)Crear  signal  para  agregar  un   objeto  Profile  a  cada  objeto   User  creado.c) Eliminar  BD.d)Hacer  syncdbUsers  en  dwiger 333. Followers 334. Profile models.py 335. Profilemodels.pyclass Profile(models.Model): user = models.OneToOneField(User, unique=True) bio = models.CharField(blank=True, max_length=200) 336. Profilemodels.pyclass Profile(models.Model): user = models.OneToOneField(User, unique=True) bio = models.CharField(blank=True, max_length=200) followers = models.ManyToManyField("self", blank=True, 337. Profilemodels.pyclass 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, 338. Profilemodels.pyclass 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") 339. Profilemodels.pyclass 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") •  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 340. a) Añadir  ManyToMany  para  los  followers.b)Eliminar  BD.c) Hacer  syncdb Users  en  dwiger 341. 1,2,3  Borrar  la  BD....  1,2,3...  Borrar  la  BD 342. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 343. CRUD:  Create,  Retrieve,  Update  &  Delete 344. django.contrib.admin12 3 345. django.contrib.admin12 3 346. django.contrib.admin1 347. Django  admin:  Instalación urls.pyfrom django.conf.urls.defaults import *# Uncomment the next two lines to enable the admin:# from django.contrib import admin1# admin.autodiscover()urlpatterns = patterns(,...2 # (r^admin/, include(admin.site.urls)),...) 348. Django  admin:  Instalación urls.pyfrom django.conf.urls.defaults import *# Uncomment the next two lines to enable the admin:from django.contrib import admin1admin.autodiscover()urlpatterns = patterns(,...2 (r^admin/, include(admin.site.urls)),...) 349. Django  admin:  Instalación sesngs.pyINSTALLED_APPS = (django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.sites,...) 350. Django  admin:  Instalación sesngs.pyINSTALLED_APPS = (django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.sites,django.contrib.admin, 1...) 351. Actualizando  la  BD 352. Actualizando  la  BD$ python manage.py syncdb Creating table django_admin_log Installing index for admin.LogEntry model Admin  lista  para  usar 353. ¿Y  nuestra  app?? 354. ¿Y  nuestra  app? 355. admin.py• Cada  app  debe  de  tener  el  suyo.• Define  qué  modelos  serán  visibles  desde  el  admin  y   permite  personalizar  su  aspecto.from django.contrib import adminfrom website.models import Tweetclass TweetAdmin(admin.ModelAdmin):list_display = (id,user,message,timestamp)admin.site.register(Tweet, TweetAdmin) 356. a) Configurar  urls.pyb)Configurar  sesngs.pyc) Hacer  syncdbd)Comprobar  que  no  está  Tweet.e) Añadir  admin.pyf) Probar  Administración. Instalar  Admin 357. Fixtures 358. 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: 359. 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 360. 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 •  Se  cargan  uHlizando: python manage.py loaddata •  Si  se  llaman  iniAal_data  y  están  dentro  de  la  carpeta  fixtures  de  la  app,  se  cargan  al  ahcer  el  syncdb. 361. a) Crear  la  carpeta  website/fixtures.b)Introducir  datos  desde  el  panel   Admin  y  hacer  un  dumpdata  que   guarde  un  fixture  con  nombre   initial_data.json  en  la  carpeta   fixtures.c) Hacer  syncdbEl  poder  de  los  fixtures 362. Tarea  5:  Avance  en  dwiger a) Implementar  la  vista  user_page()  para  ofrecer  un  perfil  de  usuario  con  su  Hmeline  personal:‣ URL:    user//‣ View:    user_page‣ Template:    user_page.html    (Descargar) 363. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 364. Formularios 365. Clases  involucradas 366. Clases  involucradasWidget Componente  visual  equivalente  a  HTML TextInput CheckboxInput 367. Clases  involucradasWidget Componente  visual  equivalente  a  HTML TextInput CheckboxInput FieldLógica  de  un  campo,  asociado  a  un  Widget EmailField widget, initial, error, ... IPAddressField 368. Clases  involucradasWidget Componente  visual  equivalente  a  HTML TextInput CheckboxInput FieldLógica  de  un  campo,  asociado  a  un  Widget EmailField widget, initial, error, ... IPAddressField FormConjunto  de  Fields  de  un  formulario ContactForm [nombre, email, telefono, mensaje, ...] 369. Fields 370. Fields■ BooleanField■ IPAddressField■ CharField ■ MultipleChoiceField■ ChoiceField ■ NullBooleanField■ TypedChoiceField■ RegexField■ DateField ■ SlugField■ DateTimeField ■ TimeField■ DecimalField■ URLField■ EmailField■ ComboField■ FileField ■ MultiValuefield■ FilePathField ■ SplitDateTimeField■ FloatField■ ModelChoiceField■ ImageField■ ModelMultipleChoiceField■ IntegerField 371. Fields■ BooleanField■ IPAddressField■ CharField ■ MultipleChoiceField■ ChoiceField ■ NullBooleanField■ TypedChoiceField■ RegexField■ DateField ■ SlugField■ DateTimeField ■ TimeField■ DecimalField■ URLField■ EmailField■ ComboField■ FileField ■ MultiValuefield■ FilePathField ■ SplitDateTimeField■ FloatField■ ModelChoiceField■ ImageField■ ModelMultipleChoiceField■ IntegerField 372. Creación  de  un  Form• Paso  1/3:  Definición  del  formulario  en  forms.pyfrom django import formsclass ContactForm(forms.Form): subject = forms.CharField(max_length=100, label=Topic) email = forms.EmailField(required=False) message = forms.CharField(widget=forms.Textarea) 373. Creación  de  un  Form• Paso  2/3:  Maquetación  del  formulario  en  su  templateContact us{% if form.errors %}Please correct the error{{ form.errors|pluralize }} below.{% endif %}{{ form.as_table }} 374. Creación  de  un  Form• Paso  3/3:  Programación  de  la  vista  en  views.pyfrom django.shortcuts import render_to_responsefrom mysite.contact.forms import ContactFormdef contact(request): if request.method == POST: form = ContactForm(request.POST) if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/) else: form = ContactForm() return render_to_response(contact_form.html, {form: form}) 375. Creación  de  un  Form• Paso  3/3:  Programación  de  la  vista  en  views.pyfrom django.shortcuts import render_to_responsefrom mysite.contact.forms import ContactFormdef contact(request): if request.method == POST: Pa gern form = ContactForm(request.POST) if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/) else: form = ContactForm() return render_to_response(contact_form.html, {form: form}) 376. Creación  de  un  Form• Paso  3/3:  Programación  de  la  vista  en  views.pyfrom django.shortcuts import render_to_responsefrom mysite.contact.forms import ContactFormdef contact(request): if request.method == POST: Pa gern form = ContactForm(request.POST) if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/) else: form = ContactForm() return render_to_response(contact_form.html, {form: form}) 377. Creación  de  un  Form• Paso  3/3:  Programación  de  la  vista  en  views.pyfrom django.shortcuts import render_to_responsefrom mysite.contact.forms import ContactFormdef contact(request): if request.method == POST:Pa gern form = ContactForm(request.POST) if form.is_valid():cd = form.cleaned_datasend_mail(cd[subject], cd[message], ...)# ...return HttpResponseRedirect(/contact/thanks/) else: form = ContactForm() return render_to_response(contact_form.html, {form: form}) 378. Validación  propia Podemos  programar  validación  extra  asociada  a  cada  Field  del  formulario  escribiendo  un  método  clean_:from django import formsclass ContactForm(forms.Form): subject = forms.CharField(max_length=100) email = forms.EmailField(required=False) message = forms.CharField(widget=forms.Textarea) def clean_message(self):message = self.cleaned_data[message]num_words = len(message.split())if num_words < 4:raise forms.ValidationError("Not enough words!")return message 379. Validación  propia Podemos  programar  validación  extra  asociada  a  cada  Field  del  formulario  escribiendo  un  método  clean_:from django import formsclass ContactForm(forms.Form): subject = forms.CharField(max_length=100) email = forms.EmailField(required=False) message = forms.CharField(widget=forms.Textarea) def clean_message(self):message = self.cleaned_data[message]num_words = len(message.split())if num_words < 4:raise forms.ValidationError("Not enough words!")return message 380. Maquetación  propia Podemos  personalizar  la  maquetación  tanto  como   queramos,  prescindiendo  de  las  ayudas  de  form.as_table:...{{ form.subject.errors }} Para  los  diseñadores:Subject:{{ form.subject }} ul.errorlist {...{{ form.email.errors }}}E-mail:.errorlist li {{{ form.email }} ... }...... 381. Forms  a  parHr  de  Models:  El  COLMO  del  DRY 382. Forms  a  par/r  de  Modelsfrom django.db import modelsclass Author(models.Model):models.py name = models.CharField(max_length=100)birth_date = models.DateField(blank=True, null=True)country = models.ModelChoiceField(Country)...from django import formsfrom books.models import Author forms.py class AuthorForm(forms.ModelForm):class Meta:model = Authorexclude = (country,) 383. a) Crear  un  Form  que  permita  publicar   tweets  desde  Hmeline.html  al   usuario  que  esté  logueado  desde   django.contrib.admin  (no  tenemos   login  propio).Primer  Form  en  dwiger 384. Tarea  6:  Avance  en  dwiger a) Implementar  la  vista  users_list()  para  visualizar  la  lista  de  usuarios:‣ URL:    users/‣ View:    users_list‣ Template:    users_list.html    (Descargar) 385. Índice1. Python 2. Djangoa. Introducción a. Introducciónb. Tipos  de  datos b. URLs  y  Vistasc. Operadores c. Templates Proyectod. Usos  frecuentes d. Modeloe. Estructurase. Administraciónf. Sentencias f. Formulariosg. Ejerciciog. Magia  avanzada 386. Magia  avanzada 387. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 388. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 389. Views  avanzadas¡El  primer  parámetro  de  paherns()  sirve  de  algo! from django.conf.urls.defaults import * urlpatterns = patterns(, (r^hello/$, mysite.views.hello), (r^time/$, mysite.views.current_datetime), (r^time/plus/(d{1,2})/$, mysite.views.hours_ahead), ) 390. Views  avanzadas¡El  primer  parámetro  de  paherns()  sirve  de  algo! from django.conf.urls.defaults import * urlpatterns = patterns(, (r^hello/$, mysite.views.hello), (r^time/$, mysite.views.current_datetime), (r^time/plus/(d{1,2})/$, mysite.views.hours_ahead), ) from django.conf.urls.defaults import * urlpatterns = patterns(mysite.views, (r^hello/$, hello), (r^time/$, current_datetime), (r^time/plus/(d{1,2})/$, hours_ahead), ) 391. Views  avanzadasEn  ficheros  urls.py  que  gesHonen  varias  apps...from django.conf.urls.defaults import *urlpatterns = patterns(mysite.views,(r^hello/$, hello),(r^time/$, current_datetime),(r^time/plus/(d{1,2})/$, hours_ahead),)urlpatterns += patterns(weblog.views,(r^tag/(w+)/$, tag),) 392. Views  avanzadasEn  ficheros  urls.py  que  gesHonen  varias  apps...from django.conf.urls.defaults import *urlpatterns = patterns(mysite.views,(r^hello/$, hello),(r^time/$, current_datetime),(r^time/plus/(d{1,2})/$, hours_ahead),)urlpatterns += patterns(weblog.views,(r^tag/(w+)/$, tag),) 393. Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps? 394. Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps? 395. Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps? 396. Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps? 397. NUNCA 398. NUNCAINFRAVALORÉIS 399. NUNCAINFRAVALORÉIS  PODERel 400. NUNCAINFRAVALORÉIS  PODERel    PONYde un 401. NUNCAINFRAVALORÉIS  PODERel    PONYde un ROSA 402. Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps? 403. Views  avanzadas¿Dónde  somos  capaces  de  reu/lizar  código  entre  apps? 404. Views  avanzadas Generic  ViewsVistas  con  funcionalidad  genérica  parametrizable  mediante  un  diccionario  de  Extra  Op/ons Las  tuplas  de  paherns()  pueden  tener  3  elementosfrom django.conf.urls.defaults import *from mysite import viewsurlpatterns = patterns(,(r^foo/$, views.foobar_view, {template_name: template1.html}),(r^bar/$, views.foobar_view, {template_name: template2.html}),) 405. Views  avanzadas from django.views.generic.simple import direct_to_template Renderiza  directamente  la  template  indicadafrom django.conf.urls.defaults import *from django.views.generic.simple import direct_to_templateurlpatterns = patterns(,(r^about/$, direct_to_template, {template: about.html})) Es  la  Generic  View  más  simple  y  más  uHlizada 406. 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:    logout.html    (Descargar)Extra  OpHons  en  urls.py 407. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 408. Context  ProcessorsProblema ! ! ! ! ! ! ! ! 409. Context  Processors Solución:  el  objeto  RequestContext() c = RequestContext(request, {tweets: tweets})• Sus7tuye  a  Context().• Recibe  un  HMpRequest()  antes  del  diccionario.• Automá7camente  alimenta  nuestro  diccionario  con  todos  los  diccionarios  devueltos  por  los  Context  Processors  que  tengamos  habilitados. 410. Context  Processors ¿Context  Processors?  Son  funciones.• Reciben  un  HMpRequest()  como  único  parámetro.• Devuelven  un  diccionario  para  ser  usado  como  Context(). 411. Context  Processors ¿Context  Processors?  Son  funciones.• Reciben  un  HMpRequest()  como  único  parámetro.• Devuelven  un  diccionario  para  ser  usado  como  Context().def ip_address_processor(request):return {ip_address: request.META[REMOTE_ADDR]} 412. Context  Processors ¿Context  Processors?  Son  funciones.• Reciben  un  HMpRequest()  como  único  parámetro.• Devuelven  un  diccionario  para  ser  usado  como  Context().def ip_address_processor(request):return {ip_address: request.META[REMOTE_ADDR]}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",) 413. Context  Processors¿Qué  ocurre  con  render_to_response()?def some_view(request):# ...return render_to_response(my_template.html, my_data_dictionary, context_instance=RequestContext(request)) 414. Context  Processors¿Qué  ocurre  con  render_to_response()?def some_view(request): # ...return render_to_response(my_template.html, my_data_dictionary, context_instance=RequestContext(request)) 415. Context  Processors¿Qué  ocurre  con  render_to_response()?def some_view(request): # ...return render_to_response(my_template.html, my_data_dictionary, context_instance=RequestContext(request)) Consejofrom django.shortcuts import render_to_responsefrom django.template import RequestContextdef render_response(req, *args, **kwargs): kwargs[context_instance] = RequestContext(req) return render_to_response(*args, **kwargs) 416. a) Crear  un  fichero  [email protected]  en  la  raíz   del  proyecto  que  implemente  la   función  render_response().b)Cambiar  todas  las  vistas  para  que   uHlicen  render_response()  e   incluyan  así  todos  los   ContextProcessors  disponibles.ContextProcessors  en  dwiger 417. c) Añadir  en  la  cabecera  de  todas  las   páginas  (en  base.html)  un  mensaje   de  bienvenida  al  usuario  logueado:   Bienvenido,  .d)Si  no  hay  ningún  usuario  logueado,   habrá  que  mostrar  un  enlace   Entrar  que  nos  lleve  a  /login.ContextProcessors  en  dwiger 418. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 419. Template  LibraryNos  permite  extender  el  sistema  de  templates  de  Django  con  Filters  y  Tags  propios 420. Template  LibraryNos  permite  extender  el  sistema  de  templates  de  Django  con  Filters  y  Tags  propios Uso{% load milibreria %}...{{ variable|mifiltro:"param" }}...{% mitag param1 param2 %} 421. Template  LibraryNos  permite  extender  el  sistema  de  templates  de  Django  con  Filters  y  Tags  propios UsoCreación{% load milibreria %}...{{ variable|mifiltro:"param" }}...{% mitag param1 param2 %} 422. Custom  FiltersUn  Filter  es  una  función  Python  que:• Recibe  1  o  2  argumentos:  (value  [,  arg]).• Siempre  devuelve  algo:  el  resultado,  value  o  "".• Falla  silenciosamente:  no  lanza  excepciones. 423. Custom  FiltersUn  Filter  es  una  función  Python  que:• Recibe  1  o  2  argumentos:  (value  [,  arg]).• Siempre  devuelve  algo:  el  resultado,  value  o  "".• Falla  silenciosamente:  no  lanza  excepciones. from django import template register = template.Library()Ejemplodef cut(value, arg= ): return value.replace(arg, ) register.filter(cut, cut) 424. Custom  FiltersUn  Filter  es  una  función  Python  que:• Recibe  1  o  2  argumentos:  (value  [,  arg]).• Siempre  devuelve  algo:  el  resultado,  value  o  "".• Falla  silenciosamente:  no  lanza  excepciones. from django import template register = template.Library() @register.filter(name=cut) def cut(value, arg= ): return value.replace(arg, ) 425. Custom  FiltersUn  Filter  es  una  función  Python  que: • Recibe  1  o  2  argumentos:  (value  [,  arg]). • Siempre  devuelve  algo:  el  resultado,  value  o  "". • Falla  silenciosamente:  no  lanza  excepciones. from django import template Py thon   register = template.Library()2.4  se  hizo   @register.filter(name=cut) sexydef cut(value, arg= ): return value.replace(arg, ) 426. a) Crear  un  Filter  llamado  |mention   que  al  detectar  un  “@usuario”   convierta  ese  texto  en  un  enlace  al   perfil  de  dwiger  de  ese  usuario.Nuestro  propio  Filter  en  dwiger 427. Custom  TagsEl  método  genérico  para  crear  Tags  es  complejo.Vamos  a  ver  cómo  crear  los  2  Hpos  de  Tags  más  sencillos:SimpleTags InclusionTags• Son  inline • Son  inline• Reciben  1  argumento • Reciben  n  argumentos• Devuelven  un  string • Devuelven  un  diccionario• Insertan  su  propio   fragmento  de  template 428. SimpleTagsEjemplo:  Devolver  la  hora  actual  formateada.{% current_time "%Y-%m-%d %I:%M %p" %} 429. SimpleTags Ejemplo:  Devolver  la  hora  actual  formateada. {% current_time "%Y-%m-%d %I:%M %p" %}from django import templateregister = template.Library()@register.simple_tagdef current_time(format):try: return datetime.datetime.now().strftime(str(format))except UnicodeEncodeError: return 430. InclusionTagsEjemplo:  Mostar  un  link  de  ‘follow’  o  uno  de  ‘unfollow’. {% follow_or_unfollow_link user.get_profile otherprofile %} 431. InclusionTagsEjemplo:  Mostar  un  link  de  ‘follow’  o  uno  de  ‘unfollow’. {% follow_or_unfollow_link user.get_profile otherprofile %} @register.inclusion_tag(website/follow_or_unfollow.html) def follow_or_unfollow_link(me, user): subcontext = {} if user in me.following.all(): subcontext[is_friend] = True else: subcontext[is_friend] = False subcontext[target_user] = user return subcontext 432. InclusionTagsEjemplo:  Mostar  un  link  de  ‘follow’  o  uno  de  ‘unfollow’. {% follow_or_unfollow_link user.get_profile otherprofile %} @register.inclusion_tag(website/follow_or_unfollow.html) def follow_or_unfollow_link(me, user): subcontext = {} if user in me.following.all(): subcontext[is_friend] = True else: subcontext[is_friend] = False subcontext[target_user] = user return subcontext {% if is_friend %} unfollow {% else %} follow {% endif %} 433. a) Crear  un  Tag  llamado  follow_or_unfollow_link  que  permita  pintar  un  enlace  de  ‘follow’  o  ‘unfollow’  junto  a  cada  usuario  dwiger  que  aparece  listado  en  users_page.htmlNuestro  propio  TemplateTag  en  dwiger 434. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 435. Middleware Nos  permite  escribir  funcionalidad  reu7lizable  que  se  inserta  en  el  flujo  de  ejecución  de  Django 436. Middlewareclass MyMiddleware(object):def process_request(self, request):"""Se ejecuta antes de que Django decida a qué View llamar. -> HttpRequest(): Se corta el flujo de middleware. -> None: El flujo sigue con el siguiente middleware."""# ...def process_view(self, request, view_func, view_args, view_kwargs):"""Se ejecuta antes de que se llame a la View. -> HttpRequest(): Se corta el flujo de middleware. -> None: El flujo sigue con el siguiente middleware."""# ...def process_response(self, request, response):"""Se ejecuta después de que la View devuelva una response. -> HttpResponse()"""# ...def process_exception(self, request, exception):"""Se ejecuta cuando una View lanza una excepción. -> HttpResponse(). -> None: La excepción se propaga hasta el cliente."""# ... 437. MiddlewareTenemos  que  incluir  nuestro  middleware  en  el  lugar  que  nos  convenga,  teniendo  en  cuenta  el  orden  de   ejecución  en  la  Request  y  en  la  Response:MIDDLEWARE_CLASSES = ( django.middleware.common.CommonMiddleware, django.contrib.sessions.middleware.SessionMiddleware, django.middleware.csrf.CsrfViewMiddleware, django.contrib.auth.middleware.AuthenticationMiddleware, django.contrib.messages.middleware.MessageMiddleware,) 438. Middleware1. Sistema  de  BETA1. Nos  aseguramos  de  controlar  todas  páginas.2. Si  el  usuario  Hene  una  IP  o  un  User  o...2. Si@o  en  Mantenimiento1. Todo  el  Site  muestra  un  splash  excepto...3. Cache  Middleware1. Si  la  vista  cumple  un  patrón  (User  no  logeado,...)  cacheamos  la  página.4.  etc... 439. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 440. InternacionalizaciónOfrece  integración  con  la  librería  GNU  gehext  de  i18n1. Un  fichero  .pot  conHene  todos  los  strings  usadoscontabilidad.pot2. En  cada  fichero  .po  se  guarda  una  traducciónes_ES.pot      es_AR.pot      en_GB.pot3. Cada  .po  se  compila  y  genera  un  .mo  binarioes_ES.mo      es_AR.mo      en_GB.mo 441. Internacionalización• ¿Cómo  indicar  qué  strings  deben  ser  traducidos?• GesHón  cómoda  de  singulares  y  plurales 442. Internacionalización• ¿Cómo  indicar  qué  strings  deben  ser  traducidos?from django.utils.translation import ugettext as _print _("Cadena de texto")• GesHón  cómoda  de  singulares  y  plurales 443. Internacionalización• ¿Cómo  indicar  qué  strings  deben  ser  traducidos?from django.utils.translation import ugettext as _print _("Cadena de texto")• GesHón  cómoda  de  singulares  y  pluralesfrom django.utils.translation import ungettextfrase = ungettext("Hay %(total)d resultado","Hay %(total)d resultados", total)% { total: total } 444. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 445. caching• Si  queremos  escalar  nuestro  proyecto  rápidamente....  Cache! • Recomendado  =  memcached• Acceder  a  la  BD  es  caro,  muy  caro.• El  Hardware  es  “gra7s”  en  comparación  con  op7mizar  código  op7mizado.• Ejemplo  (Facebook): 446. caching• Si  queremos  escalar  nuestro  proyecto  rápidamente....  Cache! • Recomendado  =  memcached• Acceder  a  la  BD  es  caro,  muy  caro.• El  Hardware  es  “gra7s”  en  comparación  con  op7mizar  código  op7mizado.• Ejemplo  (Facebook): 300+Tb  Memcached 447. cachingviewsfrom django.views.decorators.cache import cache_page@cache_page(60 * 15)def my_view(request):... 448. caching views from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ...templates {% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %} 449. cachinglow  level 450. cachinglow  level>>> from django.core.cache import cache>>> cache.set(my_key, hello, world!, 30)>>> cache.get(my_key)hello, world!• Podemos  cachear  cualquier  7po  de  objeto  que  se  pueda  serializar.•  QuerySets•  Listas•  ... 451. memcached  DEMO 452. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 453. Deploying  Django1. hgp://virtualenv.openplans.org/2. hgp://pip.openplans.org/3. hgp://fabfile.org/ 454. Deploying  DjangoVirtualenv  +  PIP  [+  Fabric] 1. hgp://virtualenv.openplans.org/ 2. hgp://pip.openplans.org/ 3. hgp://fabfile.org/ 455. Virtualenv• Independencia  completa  de  las  librerías  del  sitema.• Cada  proyecto  7ene  su  juego  de  librerías  en  la  versión  que  necesita• Sin  miedo  a  actualizar• Sin  miedo  a  migrar• etc... 456. Virtualenv• Independencia  completa  de  las  librerías  del  sitema.• Cada  proyecto  7ene  su  juego  de  librerías  en  la  versión  que  necesita• Sin  miedo  a  actualizar• Sin  miedo  a  migrar• etc...crear$ virtualenv --no-site-packages mi_entorno 457. Virtualenv• Independencia  completa  de  las  librerías  del  sitema.• Cada  proyecto  7ene  su  juego  de  librerías  en  la  versión  que  necesita• Sin  miedo  a  actualizar• Sin  miedo  a  migrar• etc...crear$ virtualenv --no-site-packages mi_entornoac/var$ source mi_entorno/bin/activate 458. PIP• Gestor  de  paquetes  del  siglo  21  :D• Permite  especificar  un  fichero  de  REQUIREMENTS  con  un  listado  de  paquetes  a  instalar. 459. PIP• Gestor  de  paquetes  del  siglo  21  :D• Permite  especificar  un  fichero  de  REQUIREMENTS  con  un  listado  de  paquetes  a  instalar. Django==1.2.3 psycopg2 feedparser==4.1 stripogram==1.5 GChartWrapper==0.8pip install -E mi_entorno -r REQUIREMENTS 460. a) Crear  un  entorno  virtualb)Instalar  Django==1.0c) Probar  django.VERSION Nuestro  primer  Virtualenv  +  PIP 461. Fabric“ Repetition leads to boredom, boredom to horrifying mistakes,horrifying mistakes to God-I-wish-I-was-still-bored 462. Fabric“ Repetition leads to boredom, boredom to horrifying mistakes,horrifying mistakes to God-I-wish-I-was-still-bored fabfile.pyenv.user = "example"env.hosts = ["example.com"]def deploy(): run(svn up /home/example/) sudo(/etc/init.d/lighttpd restart) 463. Fabric“ Repetition leads to boredom, boredom to horrifying mistakes,horrifying mistakes to God-I-wish-I-was-still-bored fabfile.pyenv.user = "example"env.hosts = ["example.com"]def deploy(): run(svn up /home/example/) sudo(/etc/init.d/lighttpd restart) usofabric deploy 464. nginx  +  Gunicornnginx •  nginx  [engine  x]  is  a  HTTP  and  reverse  proxy  server. •  Con  una  configuración  muy  sencilla  podremos  u7lizarlo  como  proxy   inverso  a  gunicorn. •  hMp://gunicorn.org/gunicorn •  Servidor  Web  WSGI  implementado  en  Python •  Facilidades  de  puesta  en  marcha  de  proyectos  django •  Fácilmente  configurable  usando  nginx •  hMp://nginx.org/ 465. Magia  avanzada1. Views  avanzadas2. Context  Processors3. Custom  Template  Filters  &  Tags4. Middleware5. Internacionalización6. Caching7. Despliegue8. Apps  recomendadas 466. Apps 467. django-­‐south 468. django-­‐south hMp://south.aeracode.org/•  Sistema  inteligente  para  realizar  de  manera  automá7ca  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  an7guo  Modelo  a  uno  nuevo...  south!• Necesito  que  ...  south! 469. django-­‐southcrear  primer  schema$ python manage.py schemamigration website --initialcrear  2-­‐*  migración $ python manage.py schemamigration website --autoaplicar  migraciones$ python manage.py migrate 470. django-­‐south hMp://south.aeracode.org/crear  primer  schema$ python manage.py schemamigration website --initialcrear  2-­‐*  migración $ python manage.py schemamigration website --autoaplicar  migraciones$ python manage.py migrate 471. django-­‐haystack hMp://haystacksearch.org/ 472. django-­‐haystack•  “EL”  Sistema  de  búsquedas  para  Django•  Funciona  con  varios  sistemas  de  Indexación•  Solr,  Xapian,  Whoosh•  Features:•  ‘More  like  this’• Face7ng• Highligh7ng•  Spelling  Sugges7on•  etc... hMp://haystacksearch.org/ 473. django-­‐registra/onhMp://bitbucket.org/ubernostrum/django-­‐registra7on/ 474. django-­‐registra/on• Sistema  completo  para  la  ges7ón  de  usuarios.• Desde  el  registro,  ac7vación  etc...• DRY!!• Instalación  muy  sencilla.• Recomedado  ++hMp://bitbucket.org/ubernostrum/django-­‐registra7on/ 475. django-­‐registra/onhMp://bitbucket.org/ubernostrum/django-­‐registra7on/ 476. django-­‐registra/on/ac7vate/complete//ac7vate///  register//  register/complete//  register/closed//  login//  logout//  password/change//  password/change/done//  password/reset//  password/reset/confirm//  password/reset/complete//  password/reset/done//  reac7vate/ hMp://bitbucket.org/ubernostrum/django-­‐registra7on/ 477. django-­‐socialregistra/onhMp://github.com/flashingpumpkin/django-­‐socialregistra7on 478. django-­‐socialregistra/on• Configuración  sencilla• Auten7cación  con:• twiMer,  facebook,  oauth,  openid• Integración  perfecta  con  contrib.authhMp://github.com/flashingpumpkin/django-­‐socialregistra7on 479. django-­‐debug-­‐toolbarhMp://github.com/robhudson/django-­‐debug-­‐toolbar 480. django-­‐celery 481. django-­‐celery• 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...) 482. django-­‐celeryfrom celery.decorators import task@taskdef add(x, y):return x + y>>> result = add.delay(4, 4)>>> result.wait() # wait for and return the result8 483. django-­‐celeryfrom celery.decorators import task• Las  Task  son  simples  funciones  (O  class  si  queremos)@taskdef add(x, y):• Python  100%  el  retorno  será  el  resultadoreturn x + y• Usamos  el  decorador  @task  para  registrarla• El  método  .delay  sobre  cualquier  Task  lo  >>> result = add.delay(4, 4) ejecuta  en  background.>>> result.wait() # wait for and return the result8 • Podemos  esperar  a  que  un  Worker  ejecute   la  tarea  o  seguir  haciendo  otras  acciones. 484. dajaxproject hMp://dajaxproject.com 485. dajaxproject• Comunicación  AJAX  muy  sencilla• CrossBrowsing• Muy  ú7l  si  no  sabemos  demasiado  JS• Dajaxice  no  require  ningún  Framework  de  JS• Dajax  puede  usar  cualquiera  de  los  más  conocidos  (Prototype,  jQuery,  MooTools...) hMp://dajaxproject.com 486. hMp://dajaxproject.com 487. hMp://dajaxproject.com 488. django-­‐locale-­‐urlhMp://code.google.com/p/django-­‐localeurl/ 489. django-­‐locale-­‐url•  Nos  permite  especificar  el  idioma  en  la  urlwww.example.com/en/www.example.com/es/• Mejoras  en  el  SEO• Cada  página  7ene  una  única  url.• Configuración  no  tan  sencilla,  pero  interesante. hMp://code.google.com/p/django-­‐localeurl/ 490. django-­‐pistonhMp://bitbucket.org/jespern/django-­‐piston/wiki/Home 491. django-­‐piston•  Framework  para  crear  APIs  RESTful•  Muy  fácil  instalación•  Serialización  a:• JSON,  YAML,  Python  Pyckle,  XML  ...• OAuth• Recomendado  +++++hMp://bitbucket.org/jespern/django-­‐piston/wiki/Home 492. django-­‐sentryhMp://github.com/dcramer/django-­‐sentry 493. django-­‐command-­‐extensions hMp://code.google.com/p/django-­‐command-­‐extensions/ 494. django-­‐command-­‐extensions• Extensión  para  “manage.py”• Muchas  u7lidades  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.hMp://code.google.com/p/django-­‐command-­‐extensions/ 495. django-­‐command-­‐extensions 496. django-­‐command-­‐extensions 497. django-­‐command-­‐extensions 498. django-­‐command-­‐extensions 499. Textmate  +  DjangohMps://bitbucket.org/bkerr/django-­‐textmate-­‐bundles 500. Textmate  +  Django• Shortcuts  para  crear:• Modelos• Fields• Filters• TemplateTags• Forms• AdminDurante  el  curso  lo  hemos  u7lizado.hMps://bitbucket.org/bkerr/django-­‐textmate-­‐bundles 501. La  punta  del  iceberg 502. hgp://www.djangobook.com/ 503. How  to  ...  using  Django? 504. Desarrollo  web  ágil  con  Python  y  DjangoJorge  Bas7da  PérezJaime  Irurzun  Graña   [email protected]@gmail.com @jorgebas7da @jaimeirurzun


Comments

Copyright © 2024 UPDOCS Inc.