Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Í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

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Í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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Instalación $ sudo apt-get install python http://www.python.org/download/ Snow  Leopard  incluye  las  versiones  2.5.4  y  2.6.1

Slide 12

Slide 12 text

El  Intérprete

Slide 13

Slide 13 text

El  Intérprete $ python holamundo.py hola mundo! $ Modo  Batch #!/usr/bin/env python print "hola mundo!" holamundo.py

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Í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

Slide 16

Slide 16 text

Tipos  de  datos  h@p://docs.python.org/library/stdtypes.html object

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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!

Slide 24

Slide 24 text

Í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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Í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

Slide 30

Slide 30 text

Usos  frecuentes:  list

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

Usos  frecuentes:  str

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Usos  frecuentes:  str >>> "Python mola"[1:4] 'yth' >>> "Python mola".find("mola") 7 >>> "Python mola".replace("Python", "PHP no") 'PHP no mola'

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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"

Slide 41

Slide 41 text

Usos  frecuentes:  dict

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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}

Slide 46

Slide 46 text

Usos  frecuentes:  str  %

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Usos  frecuentes:  str  % >>> "%s es muy sabio" % "Hycker" 'Hycker es muy sabio' >>> "%s sabe %i idiomas" % ("Hycker", 5) 'Hycker sabe 5 idiomas'

Slide 49

Slide 49 text

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'

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

Í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

Slide 56

Slide 56 text

{} Estructuras

Slide 57

Slide 57 text

{} Estructuras

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

def my_first_function(p1, p2): return "Hello World!" Funciones Minúsculas Palabras  separadas  por  _ Evitar  camelCase

Slide 62

Slide 62 text

def my_first_function(p1, p2): return "Hello World!" 1 2 3 Funciones Minúsculas Palabras  separadas  por  _ Evitar  camelCase PEP 8

Slide 63

Slide 63 text

Conversión  de  /pos  h@p://docs.python.org/library/func/ons.html

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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("Python Mola")  h@p://docs.python.org/library/func/ons.html

Slide 73

Slide 73 text

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("Python Mola") Y  un  muy  largo  etc...  h@p://docs.python.org/library/func/ons.html

Slide 74

Slide 74 text

Funciones  interesantes Son  sólo  un  ejemplo...  h@p://docs.python.org/library/func/ons.html

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

Funciones  de  ayuda

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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)

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

El  operador  () • Es  importante  diferenciar: funcion      vs      funcion() Clase              vs        Clase() • El  operador  ()  permite: • Invocar  funciones: • Instanciar  clases: resultado = funcion() objeto = Clase("param1")

Slide 85

Slide 85 text

Í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

Slide 86

Slide 86 text

$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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

for ($i=0; $i < 5; $i++) { echo "Number ".$count; } for i in range(4): print "Number %i" % count Sentencias:  for

Slide 89

Slide 89 text

try { $result = 3 / 0; } catch (Exception $e) { echo "Division by Zero" } try: result = 3 / 0 except: print "Division by Zero" Sentencias:  try-­‐except

Slide 90

Slide 90 text

Prueba  de  sentencias  en  consola

Slide 91

Slide 91 text

•  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

Slide 92

Slide 92 text

•  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

Slide 93

Slide 93 text

Ejemplo  Python hFp://bit.ly/ejemplo-­‐python    

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

Í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

Slide 98

Slide 98 text

Evolución  de  la  Web Desarrollo  Web 1ª  Generación 2ª  Generación 3ª  Generación HTML CGI PHP ASP JSP ... Django Rails Symfony ...

Slide 99

Slide 99 text

Frameworks  web

Slide 100

Slide 100 text

Django:  Qué  y  dónde

Slide 101

Slide 101 text

•  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

Slide 102

Slide 102 text

•  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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

La  comunidad

Slide 105

Slide 105 text

La  comunidad • django-­‐users 22.000  miembros • django-­‐developers 7.000  miembros • djangoproject.com +500.000  visitas  únicas  mensuales

Slide 106

Slide 106 text

¿Quién  usa  Django?

Slide 107

Slide 107 text

¿Quién  usa  Django?

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

All  Right?

Slide 115

Slide 115 text

All  Right? >>> import django >>> django.VERSION (1, 4, 0, 'final', 0) >>> import django Traceback (most recent call last): File "", line 1, in ImportError: No module named django

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

Bienvenidos  al  mundo  de  Oz

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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?

Slide 121

Slide 121 text

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?

Slide 122

Slide 122 text

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?

Slide 123

Slide 123 text

Let’s  enjoy

Slide 124

Slide 124 text

Crear  nuestro  proyecto de  5  ficheros  ;-­‐)

Slide 125

Slide 125 text

Crear  nuestro  proyecto $ django-admin startproject dwitter de  5  ficheros  ;-­‐)

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

sesngs.py

Slide 128

Slide 128 text

Arrancar  nuestro  proyecto de  5  ficheros  ;-­‐)

Slide 129

Slide 129 text

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.

Slide 130

Slide 130 text

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.

Slide 131

Slide 131 text

Í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

Slide 132

Slide 132 text

MVC  en  Django Modelo  =  Model Vista  =  Template Controlador  =  URL+View

Slide 133

Slide 133 text

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?

Slide 134

Slide 134 text

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

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

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

Slide 137

Slide 137 text

No content

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

¡Recuerda!:  MVC

Slide 140

Slide 140 text

Í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

Slide 141

Slide 141 text

Templates • Separan  la  lógica  de  presentación  a  una  capa  independiente. • Ficheros  independientes  (.html) • Lenguaje  independiente  (¡para  diseñadores!)

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

Templates 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) • Primera  aproximación  al  obje*vo:  Template  +  Context

Slide 144

Slide 144 text

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)

Slide 145

Slide 145 text

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)

Slide 146

Slide 146 text

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!

Slide 147

Slide 147 text

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

Slide 148

Slide 148 text

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)

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

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

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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!

Slide 153

Slide 153 text

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

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

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:

Slide 156

Slide 156 text

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

Slide 157

Slide 157 text

h@p://github.com/enjoydjango/dwi@er

Slide 158

Slide 158 text

Git

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

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ª

Slide 161

Slide 161 text

Git Ignorar  todos  los  cambios  * *  Si  no  habéis  commiteado  nada

Slide 162

Slide 162 text

Git $ git reset --hard HEAD $ git clean -fd Ignorar  todos  los  cambios  * *  Si  no  habéis  commiteado  nada

Slide 163

Slide 163 text

h@p://github.com/enjoydjango/dwi@er

Slide 164

Slide 164 text

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

Slide 165

Slide 165 text

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

Slide 166

Slide 166 text

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.

Slide 167

Slide 167 text

Templates:  {{}} Ejemplo templates Hola, {{ username }}. {'username': 'juan'} Ejemplo templates Hola, juan.

Slide 168

Slide 168 text

Filters  y  Tags

Slide 169

Slide 169 text

Filters  y  Tags

Slide 170

Slide 170 text

Filters  y  Tags {{ varible|filter }} filter

Slide 171

Slide 171 text

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

Slide 172

Slide 172 text

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

Slide 173

Slide 173 text

Templates:  tags  {%  %}

Slide 174

Slide 174 text

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

Slide 175

Slide 175 text

Templates:  tags  {%  %} {% comment %} Bu! {% endcomment %} comment for {% for elemento in lista %}
  • {{ elemento }}
  • {% endfor %}
  • Slide 176

    Slide 176 text

    Templates:  tags  {%  %} {% comment %} Bu! {% endcomment %} comment for {% for elemento in lista %}
  • {{ elemento }}
  • {% endfor %} if {% if username == "Juan" %} Hola Juan, me gustas! {% else %} Hola {{ username }}, {% endif %} == != > < >= <= in and or not
  • Slide 177

    Slide 177 text

    Templates:  tags  {%  %}

    Slide 178

    Slide 178 text

    Templates:  tags  {%  %} cycle {% for elemento in lista %}
  • {{ elemento }}
  • {% endfor %}
  • Slide 179

    Slide 179 text

    Templates:  tags  {%  %} cycle {% for elemento in lista %}
  • {{ elemento }}
  • {% endfor %} include {% include "foo/bar.html" %}
  • Slide 180

    Slide 180 text

    Templates:  tags  {%  %} cycle {% for elemento in lista %}
  • {{ elemento }}
  • {% endfor %} include {% include "foo/bar.html" %} forloop {% for elemento in lista %}
  • {{ forloop.counter }}.{{ elemento }}
  • {% endfor %}
  • Slide 181

    Slide 181 text

    Templates:  tags  {%  %} cycle {% for elemento in lista %}
  • {{ elemento }}
  • {% endfor %} include {% include "foo/bar.html" %} forloop {% for elemento in lista %}
  • {{ forloop.counter }}.{{ elemento }}
  • {% endfor %} empty {% for elemento in lista %}
  • {{ elemento }}
  • {% empty %} Sin elementos. {% endfor %}
  • Slide 182

    Slide 182 text

      Tarea:  Tags a) UHlizar  tags  para  que  el  Hmeline  se   muestre  con  el  siguiente  formato: • :     • :     • ...

    Slide 183

    Slide 183 text

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

    Slide 184

    Slide 184 text

    Templates:  Filters Ejemplo templates Hola, {{ username|title }}. {'username': 'juan'} Ejemplo templates Hola, Juan. /tle

    Slide 185

    Slide 185 text

    Templates:  Filters

    Slide 186

    Slide 186 text

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

    Slide 187

    Slide 187 text

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

    Slide 188

    Slide 188 text

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

    Slide 189

    Slide 189 text

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

    Slide 190

    Slide 190 text

    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

    Slide 191

    Slide 191 text

    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

    Slide 192

    Slide 192 text

    Templates:  Filters

    Slide 193

    Slide 193 text

    Templates:  Filters {'username': 'Juan es majo, guapo y listo'} {{ username|striptags }} striptags Juan es majo guapo y listo

    Slide 194

    Slide 194 text

    Templates:  Filters {'username': 'Juan es majo, guapo y listo'} {{ username|striptags }} striptags Juan es majo guapo y listo {{ username|truncatewords_html:4 }} truncatewords_html Juan es majo guapo ...

    Slide 195

    Slide 195 text

    Templates:  Filters {'username': 'Juan es majo, guapo y listo'} {{ username|striptags }} striptags Juan es majo guapo y listo {{ username|truncatewords_html:4 }} truncatewords_html Juan es majo guapo ... {{ username|removetags:”em a br” }} removetags Juan es majo guapo y listo

    Slide 196

    Slide 196 text

    Templates:  Filters

    Slide 197

    Slide 197 text

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

    Slide 198

    Slide 198 text

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

    Slide 199

    Slide 199 text

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

    Slide 200

    Slide 200 text

    Templates:  Filters {'lista': ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]} {{ lista|unordered_list }} unordered_list
  • States
    • Kansas
      • Lawrence
      • Topeka
    • Illinois
  • Slide 201

    Slide 201 text

    Templates:  Filters

    Slide 202

    Slide 202 text

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

    Slide 203

    Slide 203 text

    Templates:  Filters {'value': 123456789} {{ value|add:”1” }} add 123456790 {{ value|filesizeformat }} filesizeformat 117.7MB

    Slide 204

    Slide 204 text

    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

    Slide 205

    Slide 205 text

    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

    Slide 206

    Slide 206 text

    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

    Slide 207

    Slide 207 text

    Tarea:  Filters a) Añadir  a  cada  tweet  del  Hmeline  el   Hempo  transcurrido: • :    seconds  ago • :    minutes  ago • ...

    Slide 208

    Slide 208 text

    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”  

    Slide 209

    Slide 209 text

    Tarea:  Filters c) Conseguir  que  todas  las  urls  que   aparezcan  en  los  tweets  se  conviertan   en  enlaces    de  HTML.

    Slide 210

    Slide 210 text

    Herencia  de  Templates base.html Mi página personal {% block content %} Contenido por defecto. {% endblock %} hija.html {% extends "base.html" %} {% block content %} Hola desde la portada. {% endblock %}

    Slide 211

    Slide 211 text

    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

    Slide 212

    Slide 212 text

    Í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

    Slide 213

    Slide 213 text

    Modelos

    Slide 214

    Slide 214 text

    ¿SQL?

    Slide 215

    Slide 215 text

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

    Slide 216

    Slide 216 text

    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

    Slide 217

    Slide 217 text

    12  lineas  de  Python...  ¬_¬

    Slide 218

    Slide 218 text

    ORM  (Object-­‐RelaHonal  mapping)

    Slide 219

    Slide 219 text

    ORM  (Object-­‐RelaHonal  mapping)

    Slide 220

    Slide 220 text

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

    Slide 221

    Slide 221 text

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

    Slide 222

    Slide 222 text

    Fucking  Ninjas!

    Slide 223

    Slide 223 text

    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)  

    Slide 224

    Slide 224 text

    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)  

    Slide 225

    Slide 225 text

    Fucking  Awesome  Ninjas!

    Slide 226

    Slide 226 text

    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

    Slide 227

    Slide 227 text

    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

    Slide 228

    Slide 228 text

    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

    Slide 229

    Slide 229 text

    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

    Slide 230

    Slide 230 text

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

    Slide 231

    Slide 231 text

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

    Slide 232

    Slide 232 text

    ¿Es  magia?  No. •  Nombres  de  tablas  generados  automáHcamente. •  _lower() •  id  como  Primary  Key  (Personalizable) •  Las  Foreing  Key  terminan  en  _id  (Personalizable) •  Los  Hpos  de  datos  se  ajustan  en  función  del  SGBD

    Slide 233

    Slide 233 text

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

    Slide 234

    Slide 234 text

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

    Slide 235

    Slide 235 text

    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

    Slide 236

    Slide 236 text

    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

    Slide 237

    Slide 237 text

    Nuestro  primer  modelo a)Crear  modelo  Tweet b)Configurar  sesngs.py c) Ver  el  SQL  generado  con  sqlall

    Slide 238

    Slide 238 text

    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: [email protected] Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model

    Slide 239

    Slide 239 text

    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: [email protected] 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

    Slide 240

    Slide 240 text

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

    Slide 241

    Slide 241 text

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

    Slide 242

    Slide 242 text

    contrib.auth  puede  ser  el  úlHmo  :D

    Slide 243

    Slide 243 text

    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: [email protected] 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

    Slide 244

    Slide 244 text

    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: [email protected] 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

    Slide 245

    Slide 245 text

    BD  Lista  para  usarse

    Slide 246

    Slide 246 text

    BD  Lista  para  usarse

    Slide 247

    Slide 247 text

    Nuestro  primer  modelo a)Hacer  syncdb

    Slide 248

    Slide 248 text

    No content

    Slide 249

    Slide 249 text

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

    Slide 250

    Slide 250 text

    Previo:  __unicode__()

    Slide 251

    Slide 251 text

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

    Slide 252

    Slide 252 text

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

    Slide 253

    Slide 253 text

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

    Slide 254

    Slide 254 text

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

    Slide 255

    Slide 255 text

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

    Slide 256

    Slide 256 text

    INSERT

    Slide 257

    Slide 257 text

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

    Slide 258

    Slide 258 text

    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)

    Slide 259

    Slide 259 text

    UPDATE

    Slide 260

    Slide 260 text

    UPDATE >>> ... >>> p.id 52 >>> p.name = 'Apress Publishing' >>> p.save() o.save() 1

    Slide 261

    Slide 261 text

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

    Slide 262

    Slide 262 text

    DELETE

    Slide 263

    Slide 263 text

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

    Slide 264

    Slide 264 text

    DELETE >>> ps = Publisher.objects.all() >>> ps.delete() >>> ... >>> p.id 52 >>> p.delete() o.delete() queryset.delete() 1 n

    Slide 265

    Slide 265 text

    SELECT  de  1  resultado

    Slide 266

    Slide 266 text

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

    Slide 267

    Slide 267 text

    SELECT  de  1  resultado >>> Publisher.objects.get(name="Apress") .get(...) >>> Publisher.objects.get(name="Anaya") Traceback (most recent call last): ... DoesNotExist: Publisher matching query does not exist.

    Slide 268

    Slide 268 text

    SELECT  de  1  resultado >>> Publisher.objects.get(name="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.

    Slide 269

    Slide 269 text

    SELECT  de  N  resultados

    Slide 270

    Slide 270 text

    SELECT  de  N  resultados >>> Publisher.objects.all() [, ] .all()

    Slide 271

    Slide 271 text

    SELECT  de  N  resultados >>> Publisher.objects.all() [, ] .all() >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [] .filter(...)

    Slide 272

    Slide 272 text

    SELECT  de  N  resultados >>> Publisher.objects.all() [, ] .all() >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [] .filter(...) >>> Publisher.objects.exclude( country="U.S.A.", state_province="CA") [] .exclude(...)

    Slide 273

    Slide 273 text

    SELECT  de  N  resultados >>> Publisher.objects.all() [, ] .all() >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [] .filter(...) >>> Publisher.objects.exclude( country="U.S.A.", state_province="CA") [] .exclude(...) ¡Devuelven   QuerySets,  no   listas!

    Slide 274

    Slide 274 text

    get(),  filter()  y  exclude()

    Slide 275

    Slide 275 text

    get(),  filter()  y  exclude() Modelo.objects.filter(campo1="valor1", campo2="valor2") Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=)

    Slide 276

    Slide 276 text

    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

    Slide 277

    Slide 277 text

    ORDER  BY

    Slide 278

    Slide 278 text

    ORDER  BY >>> Publisher.objects.order_by("name") [, ] .order_by(...)

    Slide 279

    Slide 279 text

    ORDER  BY >>> Publisher.objects.order_by("name") [, ] .order_by(...) >>> Publisher.objects.order_by("-name") [, ]

    Slide 280

    Slide 280 text

    ORDER  BY >>> Publisher.objects.order_by("name") [, ] .order_by(...) >>> Publisher.objects.order_by("-name") [, ] >>> Publisher.objects.order_by("-name", "country") [, ] MúlHples  campos:

    Slide 281

    Slide 281 text

    ORDER  BY >>> Publisher.objects.order_by("name") [, ] .order_by(...) >>> Publisher.objects.order_by("-name") [, ] >>> Publisher.objects.order_by("-name", "country") [, ] MúlHples  campos: ¡También   devuelve   QuerySets!

    Slide 282

    Slide 282 text

    Slicing

    Slide 283

    Slide 283 text

    Slicing >>> Publisher.objects.order_by("name")[0] [n:m] >>> Publisher.objects.order_by("name")[:2] [, ] >>> Publisher.objects.order_by("name")[1:2] []

    Slide 284

    Slide 284 text

    Slicing >>> Publisher.objects.order_by("name")[0] [n:m] >>> Publisher.objects.order_by("name")[:2] [, ] >>> Publisher.objects.order_by("name")[1:2] [] LIMIT

    Slide 285

    Slide 285 text

    Slicing >>> Publisher.objects.order_by("name")[0] [n:m] >>> Publisher.objects.order_by("name")[:2] [, ] >>> Publisher.objects.order_by("name")[1:2] [] LIMIT OFFSET

    Slide 286

    Slide 286 text

    Related  Objects

    Slide 287

    Slide 287 text

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

    Slide 288

    Slide 288 text

    Related  Objects OneToOneField class Coche(models.Model): motor = OneToOneField(Motor) class Motor(models.Model): ... >>> c.motor ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros 1 1

    Slide 289

    Slide 289 text

    Related  Objects OneToOneField class Coche(models.Model): motor = OneToOneField(Motor) class Motor(models.Model): ... >>> c.motor >>> m.coche ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django 1 1

    Slide 290

    Slide 290 text

    Related  Objects

    Slide 291

    Slide 291 text

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

    Slide 292

    Slide 292 text

    Related  Objects ForeignKeyField class Blog(models.Model): ... class Post(models.Model): blog = ForeignKeyField(Blog) >>> p.blog >>> b.post_set.all() [, ...] ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django 1 n

    Slide 293

    Slide 293 text

    Related  Objects

    Slide 294

    Slide 294 text

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

    Slide 295

    Slide 295 text

    Related  Objects ManyToManyField class Post(models.Model): tags = ManyToManyField(Tag) class Tag(models.Model): ... >>> p.tags.add(t1, t2) >>> p.tags.all() [, ...] >>> t.post_set.add(p1, p2) >>> t.post_set.all() [, ...] ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django n m

    Slide 296

    Slide 296 text

    Related  Objects

    Slide 297

    Slide 297 text

    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

    Slide 298

    Slide 298 text

    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 >>> b.posts.all() [, ...] Gracias  a  nosotros Gracias  a  Django 1 n

    Slide 299

    Slide 299 text

    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 >>> b.posts.all() [, ...] Gracias  a  nosotros Gracias  a  Django 1 n Cuando  haya  2  relaciones  entre  2  modelos,  será  obligatorio

    Slide 300

    Slide 300 text

    Y  la  guinda  final:  ¡Todo  es  LAZY!

    Slide 301

    Slide 301 text

    Laziness

    Slide 302

    Slide 302 text

    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é] [] len(Publisher.objects.all()) list(Publisher.objects.all()) if Publisher.objects.filter(country='USA'):

    Slide 303

    Slide 303 text

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

    Slide 304

    Slide 304 text

    Usando  el  ORM c) Implementar  la  vista  tweet_page()  como   permalink  de  un  tweet: ‣ URL:    tweet// ‣ 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

    Slide 305

    Slide 305 text

    Profiles

    Slide 306

    Slide 306 text

    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.

    Slide 307

    Slide 307 text

    Profile models.py

    Slide 308

    Slide 308 text

    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.

    Slide 309

    Slide 309 text

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

    Slide 310

    Slide 310 text

    Profile >>> from django.contrib.auth.models import User >>> u = User.objects.get(id=1) >>> type(u) >>> type(u.profile) •Donde  tengamos  el  User  tendremos  el  Profile. •Donde  tengamos  el  Profile,  tendremos  el  User.

    Slide 311

    Slide 311 text

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

    Slide 312

    Slide 312 text

    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/

    Slide 313

    Slide 313 text

    Signals

    Slide 314

    Slide 314 text

    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

    Slide 315

    Slide 315 text

    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

    Slide 316

    Slide 316 text

    Followers

    Slide 317

    Slide 317 text

    Profile models.py

    Slide 318

    Slide 318 text

    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

    Slide 319

    Slide 319 text

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

    Slide 320

    Slide 320 text

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

    Slide 321

    Slide 321 text

    Í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

    Slide 322

    Slide 322 text

    CRUD:  Create,  Retrieve,  Update  &  Delete

    Slide 323

    Slide 323 text

    django.contrib.admin 1 2 3

    Slide 324

    Slide 324 text

    django.contrib.admin 1 2 3

    Slide 325

    Slide 325 text

    django.contrib.admin 1

    Slide 326

    Slide 326 text

    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

    Slide 327

    Slide 327 text

    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

    Slide 328

    Slide 328 text

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

    Slide 329

    Slide 329 text

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

    Slide 330

    Slide 330 text

    Actualizando  la  BD

    Slide 331

    Slide 331 text

    Actualizando  la  BD $ python manage.py syncdb Creating table django_admin_log Installing index for admin.LogEntry model Admin  lista  para  usar

    Slide 332

    Slide 332 text

    ¿Y  nuestra  app? ?

    Slide 333

    Slide 333 text

    ¿Y  nuestra  app?

    Slide 334

    Slide 334 text

    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)

    Slide 335

    Slide 335 text

    Instalar  Admin a)Configurar  urls.py b)Configurar  sesngs.py c) Hacer  syncdb

    Slide 336

    Slide 336 text

    Instalar  Admin d)Comprobar  que  no  están  Tweet  y  Profile e)Añadir  admin.py f) Probar  Administración.

    Slide 337

    Slide 337 text

    Fixtures

    Slide 338

    Slide 338 text

    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:

    Slide 339

    Slide 339 text

    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

    Slide 340

    Slide 340 text

    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  iniHal_data  y  están  dentro  de  la  carpeta  fixtures   de  la  app,  se  cargan  al  ahcer  el  syncdb.

    Slide 341

    Slide 341 text

    Tarea:  Avance  en  dwiier 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  h@p://bit.ly/user-­‐page

    Slide 342

    Slide 342 text

    Í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

    Slide 343

    Slide 343 text

    Formularios

    Slide 344

    Slide 344 text

    Clases  involucradas

    Slide 345

    Slide 345 text

    Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput CheckboxInput

    Slide 346

    Slide 346 text

    Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput CheckboxInput Field Lógica  de  un  campo,  asociado  a  un  Widget EmailField IPAddressField widget, initial, error, ...

    Slide 347

    Slide 347 text

    Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput CheckboxInput 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, ...]

    Slide 348

    Slide 348 text

    Fields

    Slide 349

    Slide 349 text

    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

    Slide 350

    Slide 350 text

    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

    Slide 351

    Slide 351 text

    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

    Slide 352

    Slide 352 text

    Creación  de  un  Form

    Contact us

    {% if form.errors %}

    Please correct the error{{ form.errors|pluralize }} below.

    {% endif %} {{ form.as_table }} • Paso  2/3:  Maquetación  del  formulario  en  su  template

    Slide 353

    Slide 353 text

    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

    Slide 354

    Slide 354 text

    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

    Slide 355

    Slide 355 text

    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

    Slide 356

    Slide 356 text

    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

    Slide 357

    Slide 357 text

    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_:

    Slide 358

    Slide 358 text

    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_:

    Slide 359

    Slide 359 text

    Maquetación  propia ...
    {{ form.subject.errors }} Subject: {{ form.subject }}
    {{ form.email.errors }} E-mail: {{ form.email }}
    ... ... Podemos  personalizar  la  maquetación  tanto  como   queramos,  prescindiendo  de  las  ayudas  de  form.as_table: ul.errorlist { ... } .errorlist li { ... } Para  los  diseñadores:

    Slide 360

    Slide 360 text

    Forms  a  parHr  de  Models:  El  COLMO  del  DRY

    Slide 361

    Slide 361 text

    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

    Slide 362

    Slide 362 text

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

    Slide 363

    Slide 363 text

    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

    Slide 364

    Slide 364 text

    Í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

    Slide 365

    Slide 365 text

    Magia  avanzada

    Slide 366

    Slide 366 text

    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

    Slide 367

    Slide 367 text

    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

    Slide 368

    Slide 368 text

    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!

    Slide 369

    Slide 369 text

    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!

    Slide 370

    Slide 370 text

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

    Slide 371

    Slide 371 text

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

    Slide 372

    Slide 372 text

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

    Slide 373

    Slide 373 text

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

    Slide 374

    Slide 374 text

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

    Slide 375

    Slide 375 text

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

    Slide 376

    Slide 376 text

    ROSA

    Slide 377

    Slide 377 text

    NUNCA ROSA

    Slide 378

    Slide 378 text

    NUNCA INFRAVALORÉIS ROSA

    Slide 379

    Slide 379 text

    NUNCA INFRAVALORÉIS EL  PODER ROSA

    Slide 380

    Slide 380 text

    NUNCA INFRAVALORÉIS EL  PODER DE  UN   PONY ROSA

    Slide 381

    Slide 381 text

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

    Slide 382

    Slide 382 text

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

    Slide 383

    Slide 383 text

    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

    Slide 384

    Slide 384 text

    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

    Slide 385

    Slide 385 text

    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

    Slide 386

    Slide 386 text

    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

    Slide 387

    Slide 387 text

    Context  Processors ! ! ! !

    Slide 388

    Slide 388 text

    Context  Processors ¿Context  Processors?  Son  funciones. • Reciben  un  HFpRequest()  como  único  parámetro. • Devuelven  un  diccionario  para  ser  usado  como  Context().

    Slide 389

    Slide 389 text

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

    Slide 390

    Slide 390 text

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

    Slide 391

    Slide 391 text

    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)

    Slide 392

    Slide 392 text

    ContextProcessors  en  dwiier c) Cuando  el  usuario  esté  logueado,   mostrar  Bienvenido,    y   un  link  para  desloguearse. d)Cuando  no  esté  logueado,  mostrar   un  link  a  /login. e)Tip:  user.is_authenHcated()

    Slide 393

    Slide 393 text

    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

    Slide 394

    Slide 394 text

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

    Slide 395

    Slide 395 text

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

    Slide 396

    Slide 396 text

    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

    Slide 397

    Slide 397 text

    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.

    Slide 398

    Slide 398 text

    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

    Slide 399

    Slide 399 text

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

    Slide 400

    Slide 400 text

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

    Slide 401

    Slide 401 text

    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.

    Slide 402

    Slide 402 text

    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

    Slide 403

    Slide 403 text

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

    Slide 404

    Slide 404 text

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

    Slide 405

    Slide 405 text

    InclusionTags Ejemplo:  Mostar  anuncios  si  el  usuario  no  es  premium. {% show_adverts user %} {% for advert in adverts %} {% endfor %} adverts.html milibreria.py

    Slide 406

    Slide 406 text

    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 %} {% endfor %} adverts.html milibreria.py

    Slide 407

    Slide 407 text

    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

    Slide 408

    Slide 408 text

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

    Slide 409

    Slide 409 text

    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

    Slide 410

    Slide 410 text

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

    Slide 411

    Slide 411 text

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

    Slide 412

    Slide 412 text

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

    Slide 413

    Slide 413 text

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

    Slide 414

    Slide 414 text

    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

    Slide 415

    Slide 415 text

    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

    Slide 416

    Slide 416 text

    Internacionalización • ¿Cómo  indicar  qué  strings  deben  ser  traducidos? • GesHón  cómoda  de  singulares  y  plurales

    Slide 417

    Slide 417 text

    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

    Slide 418

    Slide 418 text

    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

    Slide 419

    Slide 419 text

    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

    Slide 420

    Slide 420 text

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

    Slide 421

    Slide 421 text

    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

    Slide 422

    Slide 422 text

    caching from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ... views

    Slide 423

    Slide 423 text

    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

    Slide 424

    Slide 424 text

    caching low  level

    Slide 425

    Slide 425 text

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

    Slide 426

    Slide 426 text

    memcached  DEMO

    Slide 427

    Slide 427 text

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

    Slide 428

    Slide 428 text

    ¿y  para  500k  Usuarios?

    Slide 429

    Slide 429 text

    ¿y  para  2Millones?

    Slide 430

    Slide 430 text

    ¿y  para  ++10Millones?

    Slide 431

    Slide 431 text

    ¿y  para  ++10Millones?

    Slide 432

    Slide 432 text

    redis

    Slide 433

    Slide 433 text

    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.

    Slide 434

    Slide 434 text

    redis

    Slide 435

    Slide 435 text

    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

    Slide 436

    Slide 436 text

    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!

    Slide 437

    Slide 437 text

    redis  DEMO

    Slide 438

    Slide 438 text

    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

    Slide 439

    Slide 439 text

    Deploying  Django 1. hip://virtualenv.openplans.org/ 2. hip://pip.openplans.org/

    Slide 440

    Slide 440 text

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

    Slide 441

    Slide 441 text

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

    Slide 442

    Slide 442 text

    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

    Slide 443

    Slide 443 text

    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

    Slide 444

    Slide 444 text

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

    Slide 445

    Slide 445 text

    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

    Slide 446

    Slide 446 text

    Nuestro  primer  Virtualenv  +  PIP a)Crear  un  entorno  virtual b)Instalar  Django==1.0 c) Probar  django.VERSION

    Slide 447

    Slide 447 text

    El  Stack

    Slide 448

    Slide 448 text

    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/

    Slide 449

    Slide 449 text

    nginx  :80 gunicorn Django WSGI  Server Frontend Deploy sencillo worker  1 worker  2 worker  n

    Slide 450

    Slide 450 text

    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

    Slide 451

    Slide 451 text

    Fabric

    Slide 452

    Slide 452 text

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

    Slide 453

    Slide 453 text

    $ fab deploy -R test

    Slide 454

    Slide 454 text

    $ fab deploy -R www

    Slide 455

    Slide 455 text

    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

    Slide 456

    Slide 456 text

    Apps

    Slide 457

    Slide 457 text

    django-­‐south

    Slide 458

    Slide 458 text

    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/

    Slide 459

    Slide 459 text

    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

    Slide 460

    Slide 460 text

    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

    Slide 461

    Slide 461 text

    django-­‐haystack  h@p://haystacksearch.org

    Slide 462

    Slide 462 text

    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

    Slide 463

    Slide 463 text

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

    Slide 464

    Slide 464 text

    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/

    Slide 465

    Slide 465 text

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

    Slide 466

    Slide 466 text

    django-­‐registra/on /ac*vate/complete/ /ac*vate// /  register/ /  register/complete/ /  register/closed/ /  login/ /  logout/ /  password/change/ /  password/change/done/ /  password/reset/ /  password/reset/confirm/ /  password/reset/complete/ /  password/reset/done/ /  reac*vate/  h@p://bitbucket.org/ubernostrum/django-­‐registra/on/

    Slide 467

    Slide 467 text

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

    Slide 468

    Slide 468 text

    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

    Slide 469

    Slide 469 text

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

    Slide 470

    Slide 470 text

    Celery  h@p://celeryproject.org

    Slide 471

    Slide 471 text

    •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

    Slide 472

    Slide 472 text

    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

    Slide 473

    Slide 473 text

    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

    Slide 474

    Slide 474 text

    dajaxproject.com

    Slide 475

    Slide 475 text

    •  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

    Slide 476

    Slide 476 text

    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

    Slide 477

    Slide 477 text

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

    Slide 478

    Slide 478 text

    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.

    Slide 479

    Slide 479 text

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

    Slide 480

    Slide 480 text

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

    Slide 481

    Slide 481 text

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

    Slide 482

    Slide 482 text

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

    Slide 483

    Slide 483 text

    •  Manipular  el  DOM  usando  Python. •  Sin  necesidad  de  conocer  JS  en  profundidad. •  Soporta  Frameworks  como Obje/vos  dajax

    Slide 484

    Slide 484 text

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

    Slide 485

    Slide 485 text

    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

    Slide 486

    Slide 486 text

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

    Slide 487

    Slide 487 text

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

    Slide 488

    Slide 488 text

    DEMO

    Slide 489

    Slide 489 text

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

    Slide 490

    Slide 490 text

    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/

    Slide 491

    Slide 491 text

    Sentry    -­‐  getsentry.com  h@p://getsentry.com

    Slide 492

    Slide 492 text

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

    Slide 493

    Slide 493 text

    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/

    Slide 494

    Slide 494 text

    django-­‐command-­‐extensions

    Slide 495

    Slide 495 text

    django-­‐command-­‐extensions

    Slide 496

    Slide 496 text

    django-­‐command-­‐extensions

    Slide 497

    Slide 497 text

    django-­‐command-­‐extensions

    Slide 498

    Slide 498 text

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

    Slide 499

    Slide 499 text

     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/

    Slide 500

    Slide 500 text

    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

    Slide 501

    Slide 501 text

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

    Slide 502

    Slide 502 text

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

    Slide 503

    Slide 503 text

    La  punta  del  iceberg

    Slide 504

    Slide 504 text

     h@p://www.djangobook.com

    Slide 505

    Slide 505 text

    How  to  ...  using  Django?