SlideShare una empresa de Scribd logo
1 de 347
Descargar para leer sin conexión
Juan Riaza


  @juanriaza
Don’t reinvent the wheel
https://gist.github.com/3143116
Jorge	
  Bas0da    Jaime	
  Irurzun
me@jorgebas0da.com   jaime@irurzun.com
  @jorgebas0da          @jaimeirurzun
• Legible                Sintaxis	
  intui+va	
  y	
  estricta

• Produc-vo              Entre	
  1/3	
  y	
  1/5	
  más	
  conciso	
  que	
  Java	
  o	
  C++

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

• Extenso                Standard	
  Library,	
  Third	
  par+es

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

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




                       Modo	
  Interac0vo
$ 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!
Tipos	
  de	
  datos


object




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




object




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



         bool    True     False




object




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



         bool    True     False


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




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



         bool     True     False


          str     'spam'      "guido's"         """n lines"""
object
          list    [1, [2, 'three'], 4]




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



         bool     True     False


          str     'spam'      "guido's"         """n lines"""
object
          list    [1, [2, 'three'], 4]


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




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



         bool      True     False


           str     'spam'      "guido's"         """n lines"""
object
           list    [1, [2, 'three'], 4]


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


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


             	
  h>p://docs.python.org/library/stdtypes.html
Tipos	
  de	
  datos                                      o	
  
                                                          ¡T i p ad
                                                                 mi co!
           int     1234        long   35L       float     d iná
                                                        3.1415



         bool      True     False


           str     'spam'      "guido's"         """n lines"""
object
           list    [1, [2, 'three'], 4]


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


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


             	
  h>p://docs.python.org/library/stdtypes.html
Operadores




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




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



                 a < b         a <= b       a > b
comparadores
                 a >= b        a == b       a != b




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



                 a < b         a <= b       a > b
comparadores
                 a >= b        a == b       a != b




     lógicos     a or b       a and b        not a



          	
  h>p://docs.python.org/library/operator.html
Usos	
  frecuentes:	
  list
Usos	
  frecuentes:	
  list
>>> nums = [1, 2, 3]
>>> nums[0]
1
Usos	
  frecuentes:	
  list
>>> nums = [1, 2, 3]
>>> nums[0]
1


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


>>> 2 in nums
True


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


>>> 2 in nums
True


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


>>> len(nums)
4
Usos	
  frecuentes:	
  str
Usos	
  frecuentes:	
  str
>>> "Python mola"[1:4]
'yth'
Usos	
  frecuentes:	
  str
>>> "Python mola"[1:4]
'yth'


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


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


>>> "Python mola".replace("Python", "PHP no")
'PHP no mola'
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']
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"
Usos	
  frecuentes:	
  dict
Usos	
  frecuentes:	
  dict
>>> user = {'nick': 'neo', 'age': 24}
>>> user.keys()
['nick', 'age']
>>> user.values()
['neo', 24]
Usos	
  frecuentes:	
  dict
>>> user = {'nick': 'neo', 'age': 24}
>>> user.keys()
['nick', 'age']
>>> user.values()
['neo', 24]


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


>>> user['age']       >>> user.get('age', 20)
24                    24


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


>>> user['age']       >>> user.get('age', 20)
24                    24


>>> 'nick' in user
True


>>> user.update({'nick': 'alatar', 'age': 25})
>>> user
{'nick': 'alatar', 'age': 25}
Usos	
  frecuentes:	
  str	
  %
Usos	
  frecuentes:	
  str	
  %
>>> "%s es muy sabio" % "Hycker"
'Hycker es muy sabio'
Usos	
  frecuentes:	
  str	
  %
>>> "%s es muy sabio" % "Hycker"
'Hycker es muy sabio'



>>> "%s sabe %i idiomas" % ("Hycker", 5)
'Hycker sabe 5 idiomas'
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'
Módulos
juego/
     __init__.py
                        1. Un	
  módulo	
  es	
  un	
  fichero	
  .py
     bonus/
        __init__.py
        estrella.py
        moneda.py       2. Los	
  módulos	
  pueden	
  
        planta.py
        ...
     personajes/
                           organizarse	
  en	
  paquetes.
        __init__.py
        mario.py
        luigi.py
        princesa.py     3. Un	
  paquete	
  es	
  una	
  carpeta	
  
        ...
     enemigos/
        __init__.py
                           que	
  con+ene	
  un	
  fichero	
  con	
  
        seta.py
        tortuga.py         nombre	
  __init__.py
        bomba.py
        ...
Módulos
juego/
      __init__.py
                           1. Un	
  módulo	
  es	
  un	
  fichero	
  .py
      bonus/
         __init__.py
         estrella.py
         moneda.py
                       1   2. Los	
  módulos	
  pueden	
  
         planta.py

  2
         ...
      personajes/
                              organizarse	
  en	
  paquetes.
         __init__.py   3
         mario.py
         luigi.py
         princesa.py       3. Un	
  paquete	
  es	
  una	
  carpeta	
  
         ...
      enemigos/
         __init__.py
                              que	
  con+ene	
  un	
  fichero	
  con	
  
         seta.py
         tortuga.py           nombre	
  __init__.py
         bomba.py
         ...
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
        ...
Módulos
juego/
     __init__.py
     bonus/
        __init__.py
                       >>> from juego.personajes.mario import Mario
        estrella.py
                       >>> Mario()
        moneda.py
        planta.py
        ...
     personajes/
        __init__.py    >>> from juego.personajes.mario import *
        mario.py       >>> Mario()
        luigi.py
        princesa.py
        ...
     enemigos/
                       >>> from juego import personajes
        __init__.py
                       >>> personajes.mario.Mario()
        seta.py
        tortuga.py
        bomba.py
        ...
Estructuras




 {}
Estructuras




 {}
Identación

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




        4	
  Espacios	
  para	
  la	
  identación
Identación

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




                                                    PEP 8
        4	
  Espacios	
  para	
  la	
  identación
¿PEP	
  8?
                                                                 PEP 8




•	
  Guido	
  van	
  Rossum	
  (2001)
•	
  Recomendaciones	
  de	
  es0lo
•	
  “Readability	
  counts”
•	
  “Code	
  is	
  read	
  much	
  more	
  oQen	
  than	
  it	
  is	
  wriSen.”
•	
  Muy	
  recomendable	
  importante	
  seguirlo.

                  	
  h>p://www.python.org/dev/peps/pep-­‐0008/
Funciones

def my_first_function(p1, p2):
    return "Hello World!"




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




                                               PEP 8
           Minúsculas
           Palabras	
  separadas	
  por	
  _
           Evitar	
  camelCase
Conversión	
  de	
  -pos




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




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


>>> str(2)
'2'




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


>>> str(2)
'2'


>>> float(1)
1.0




    	
  h>p://docs.python.org/library/func-ons.html
Conversión	
  de	
  -pos
>>> int(1.3)
1
                            >>> tuple([1,2,3])
                            (1, 2, 3)
>>> str(2)
'2'


>>> float(1)
1.0




    	
  h>p://docs.python.org/library/func-ons.html
Conversión	
  de	
  -pos
>>> int(1.3)
1
                            >>> tuple([1,2,3])
                            (1, 2, 3)
>>> str(2)
'2'
                            >>> list((1,2,3))
                            [1, 2, 3]
>>> float(1)
1.0




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




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




         	
  h>p://docs.python.org/library/func-ons.html
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
Funciones	
  comunes
                                      >>> type(True)
>>> len("Python Mola")
                                      <type 'bool'>
11
                                      >>> type("Python Mola")
>>> len([1,2,3,4])
                                      <type 'str'>
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
Funciones	
  comunes
                                      >>> type(True)
>>> len("Python Mola")
                                      <type 'bool'>
11
                                      >>> type("Python Mola")
>>> len([1,2,3,4])
                                      <type 'str'>
4


>>>   range(5)                        >>> sum([0,1,2,3,4])
[0,   1, 2, 3, 4]                     10
>>>   range(1,7)                      >>> sum(range(5))
[1,   2, 3, 4, 5, 6]                  10
>>>   range(1,7,2)
[1,   3, 5]
                                         Y	
  un	
  muy	
  largo	
  etc...

            	
  h>p://docs.python.org/library/func-ons.html
Funciones	
  interesantes




           Son	
  sólo	
  un	
  ejemplo...

    	
  h>p://docs.python.org/library/func-ons.html
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
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
Funciones	
  interesantes
>>> a = [1,2,3]
>>> b = [4,5,6]                           >>> round(1.2345, 2)
>>> zip(a,b)                              1.23
[(1, 4), (2, 5), (3, 6)]



>>> sorted([5,1,3,4,2])
[1, 2, 3, 4, 5]



                   Son	
  sólo	
  un	
  ejemplo...

            	
  h>p://docs.python.org/library/func-ons.html
Funciones	
  interesantes
>>> a = [1,2,3]
>>> b = [4,5,6]                           >>> round(1.2345, 2)
>>> zip(a,b)                              1.23
[(1, 4), (2, 5), (3, 6)]



>>> sorted([5,1,3,4,2])                  >>> map(str,[1,2,3,4,5])
[1, 2, 3, 4, 5]                          ['1', '2', '3', '4', '5']



                   Son	
  sólo	
  un	
  ejemplo...

            	
  h>p://docs.python.org/library/func-ons.html
Funciones	
  de	
  ayuda
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']
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)
Clases
class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

   def hello(self):
       return 'My name is %s' % self.name

           s = Student("Jorge", 24)



                  camelCase
Clases
    1              2
class Student(object):
  3 def __init__(self, name, age):
      4 self.name = name
        self.age = age

   def hello(self): 5
       return 'My name is %s' % self.name

           s = Student("Jorge", 24)


                              PEP 8
                  camelCase
El	
  operador	
  ()
• Es	
  importante	
  diferenciar:
    funcion	
  	
  	
  vs	
  	
  	
  funcion()

    Clase	
  	
  	
  	
  	
  	
  	
  vs	
  	
  	
  	
  Clase()

• El	
  operador	
  ()	
  permite:
    • Invocar	
  funciones:                                      resultado = funcion()


    • Instanciar	
  clases:                                      objeto = Clase("param1")
Sentencias:	
  if-­‐else


$name = "Jon";               name = "Jon"

if($name == "Jon"){          if name == "Jon":
    $name = "Jon Rocks!";        name = "Jon Rocks!"
}                            elif name == "Mary":
elseif($name == "Mary"){         name = "Hello Mary"
    $name = "Hello Mary";    else:
}                                name = "Who are you?"
else{
    $name = "Who are you?"
}
Sentencias:	
  while

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




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

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




      for i in range(4):
          print "Number %i" % count
Sentencias:	
  try-­‐except

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




           try:
               result = 3 / 0
           except:
               print "Division by Zero"
Conclusiones
•	
  Python	
  es	
  un	
  lenguaje	
  fácil	
  de	
  aprender.
•	
  Menos	
  código:
    •	
  Muchos	
  Muchísimos	
  menos	
  errores	
  de	
  Sintaxis.
    •	
  Mayor	
  velocidad	
  de	
  escritura.
•	
  Proto0pado...	
  U0lizado	
  por	
  grandes	
  empresas.
Conclusiones
•	
  Python	
  es	
  un	
  lenguaje	
  fácil	
  de	
  aprender.
•	
  Menos	
  código:
    •	
  Muchos	
  Muchísimos	
  menos	
  errores	
  de	
  Sintaxis.
    •	
  Mayor	
  velocidad	
  de	
  escritura.
•	
  Proto0pado...	
  U0lizado	
  por	
  grandes	
  empresas.




                                                                       etc...
Evolución	
  de	
  la	
  Web
                   Desarrollo	
  Web

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

    HTML                  PHP             Django
     CGI                  ASP              Rails
                          JSP            Symfony
                           ...              ...
Frameworks	
  web
Django:	
  Qué	
  y	
  dónde
Filosoa
•	
  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)
Filosoa
•	
  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.”
Filosoa
•	
  Explicit	
  is	
  beSer	
  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.

      	
  h>p://docs.djangoproject.com/en/dev/misc/design-­‐philosophies/
La	
  comunidad
La	
  comunidad
• django-­‐users
        22.000	
  miembros

• django-­‐developers
        7.000	
  miembros

• djangoproject.com
        +500.000	
  visitas	
  únicas	
  mensuales
¿Quién	
  usa	
  Django?
¿Quién	
  usa	
  Django?
Bienvenidos	
  al	
  mundo	
  de	
  Oz
Ficheros	
  y	
  Carpetas
            ¿Es	
  Django	
  tán	
  simple	
  y	
  fácil	
  de	
  usar?




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




Ficheros


Carpetas

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




           Rails     Symfony


Ficheros   149             117


Carpetas    35               29

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




           Rails     Symfony


Ficheros   149             117


Carpetas    35               29

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




           Rails     Symfony                        Django


Ficheros   149             117                             5


Carpetas    35               29                            2

                        *	
  Incluida	
  la	
  carpeta	
  del	
  proyecto
Let’s	
  enjoy
Crear	
  nuestro	
  proyecto
                      de	
  5	
  ficheros	
  ;-­‐)
Crear	
  nuestro	
  proyecto              de	
  5	
  ficheros	
  ;-­‐)



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



             $ django-admin startproject dwitter


                            .
                            !""      dwitter
                            #        !"" __init__.py
                            #        !"" settings.py
                            #        !"" urls.py
                            #        $"" wsgi.py
                            $""      manage.py



 -­‐	
  ¿Esto	
  es	
  un	
  proyecto...	
  ?	
  	
  	
  Si	
  os	
  ve	
  mi	
  jefe...
 -­‐	
  Sí,	
  disponemos	
  de	
  un	
  proyecto	
  ‘funcional’	
  en	
  django.
seungs.py
Arrancar	
  nuestro	
  proyecto
                        de	
  5	
  ficheros	
  ;-­‐)
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.
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.
MVC	
  en	
  Django




Modelo	
  =	
  Model   Vista	
  =	
  Template   Controlador	
  =	
  URL+View
URLs	
  y	
  Vistas
• El	
  fichero	
  urls.py	
  actúa	
  como	
  puerta	
  de	
  entrada	
  para	
  las	
  
   pe0ciones	
  HTTP

• Se	
  definen	
  URLs	
  elegantes	
  mediante	
  expresiones	
  regulares	
  
   que	
  redirigen	
  a	
  funciones	
  de	
  views.py


   hSp://mysite.com/about/                                         urls.py
                                                                           ¿urlpaSerns?



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



                                                       H>pRequest(),	
  ...


                                         views.py
                         H>pResponse()
URLs	
  y	
  Vistas
 Ejemplo	
  1:	
  	
  http://mysite.com/time

           from django.conf.urls.defaults import *
           from mysite.views import hora_actual
 urls.py   urlpatterns = patterns('',
               url(r'^time/$', hora_actual),
           )



           from django.http import HttpResponse
           from datetime import datetime

views.py   def hora_actual(request):
               now = datetime.now()
               html = "Son las %s." % now
              return HttpResponse(html)
URLs	
  y	
  Vistas
 Ejemplo	
  2:	
  	
  http://mysite.com/time/plus/2

           from django.conf.urls.defaults import *
           from mysite.views import dentro_de
 urls.py   urlpatterns = patterns('',
               url(r'^time/plus/(d{1,2})/$', dentro_de),
           )



           from django.http import HttpResponse
           from datetime import datetime, timedelta

           def dentro_de(request, offset):
views.py       offset = int(offset)
               dt = datetime.now() + timedelta(hours=offset)
               html = "En %i hora(s), serán las %s." % (offset, dt)
              return HttpResponse(html)
URLs	
  y	
  Vistas
 Ejemplo	
  2:	
  	
  http://mysite.com/time/plus/2

           from django.conf.urls.defaults import *
           from mysite.views import dentro_de
 urls.py   urlpatterns = patterns('',
               url(r'^time/plus/(d{1,2})/$', dentro_de),
           )



           from django.http import HttpResponse
           from datetime import datetime, timedelta

           def dentro_de(request, offset):
views.py       offset = int(offset)
               dt = datetime.now() + timedelta(hours=offset)
               html = "En %i hora(s), serán las %s." % (offset, dt)
              return HttpResponse(html)
¡Recuerda!:	
  MVC
Templates
• Separan	
  la	
  lógica	
  de	
  presentación	
  a	
  una	
  capa	
  independiente.
     • Ficheros	
  independientes	
  (.html)
     • Lenguaje	
  independiente	
  (¡para	
  diseñadores!)
Templates
 • Se	
  basan	
  en	
  dos	
  0pos	
  de	
  objetos:	
  Template()	
  y	
  Context().
       • Un	
  objeto	
  Template()	
  con0ene	
  el	
  string	
  de	
  salida	
  que	
  
          queremos	
  devolver	
  en	
  el	
  HSpResponse	
  (normalmente	
  
          HTML),	
  pero	
  incluyendo	
  e0quetas	
  especiales	
  de	
  Django.
       • Un	
  objeto	
  Context()	
  con0ene	
  un	
  diccionario	
  con	
  los	
  
          valores	
  que	
  dan	
  contexto	
  a	
  una	
  plan0lla,	
  los	
  que	
  deben	
  
          usarse	
  para	
  renderizar	
  un	
  objeto	
  Template().

Template:      "Bienvenido, {{ user }}."
                                                                  "Bienvenido, alatar."
 Context:      {'user': 'alatar'}
Templates
• Primera	
  aproximación	
  al	
  obje0vo:	
  Template	
  +	
  Context
         from django.http import HttpResponse
         from django.template import Template, Context
         from datetime import datetime

         PLANTILLA = """<html><body>
         Son las {{ hora }}.
         </body></html>"""

         def hora_actual(request):
             now = datetime.now()
             t = Template(PLANTILLA)
             c = Context({'hora': now})
             html = t.render(c)
             return HttpResponse(html)
Templates
• Segunda	
  aproximación	
  al	
  obje0vo:	
  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)
Templates
• Segunda	
  aproximación	
  al	
  obje0vo:	
  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)
Templates
• Segunda	
  aproximación	
  al	
  obje0vo:	
  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()            Bo ring	
  
                                               plate	
  
          fp = open('/home/django/templates/hora.html')
                                         boiler
          t = Template(fp.read())
          fp.close()                        code!
          c = Context({'hora': now})
          html = t.render(c)
          return HttpResponse(html)
Templates
• Tercera	
  aproximación	
  al	
  obje0vo:	
  get_template()
                             TEMPLATE_DIRS = (
     seungs.py                   '/home/django/templates',
                             )


       from   django.http import HttpResponse
       from   django.template.loader import get_template
       from   django.template import Context
       from   datetime import datetime

       def hora_actual(request):
           now = datetime.now()
           t = get_template('hora.html')
           c = Context({'hora': now})
           html = t.render(c)
           return HttpResponse(html)
Templates
• Tercera	
  aproximación	
  al	
  obje0vo:	
  get_template()
                             TEMPLATE_DIRS = (
     seungs.py                   '/home/django/templates',
                             )


       from   django.http import HttpResponse
       from   django.template.loader import get_template
       from   django.template import Context
       from   datetime import datetime

       def hora_actual(request):
           now = datetime.now()
           t = get_template('hora.html')
           c = Context({'hora': now})
           html = t.render(c)
           return HttpResponse(html)
Templates
• Tercera	
  aproximación	
  al	
  obje0vo:	
  get_template()
                             TEMPLATE_DIRS = (
     seungs.py                   '/home/django/templates',
                             )


       from   django.http import HttpResponse
       from   django.template.loader import get_template
       from   django.template import Context
       from   datetime import datetime

       def hora_actual(request):

                                                      S0ll	
  
           now = datetime.now()
           t = get_template('hora.html')
           c = Context({'hora': now})
           html = t.render(c)                        boring...
           return HttpResponse(html)
Templates
• Obje0vo	
  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})
Templates
• Obje0vo	
  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})




                       Bori ng...?
Templates
• Obje0vo	
  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!
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
Filosoa	
  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.
Templates:	
  {{}}
<html>
    <head>Ejemplo templates</head>
    <body>
        Hola, {{ username }}.
    </body>
</html>




     {'username': 'juan'}


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

filter   {{ varible|filter }}
Filters	
  y	
  Tags

      filter     {{ varible|filter }}


inline	
  tag   {% tag var1 var2 %}
Filters	
  y	
  Tags

      filter     {{ varible|filter }}


inline	
  tag   {% tag var1 var2 %}


block	
  tag    {% tag var1 %}
                  ...
                {% endtag %}
Templates:	
  tags	
  {%	
  %}
Templates:	
  tags	
  {%	
  %}
comment   {% comment %} Bu! {% endcomment %}
Templates:	
  tags	
  {%	
  %}
comment   {% comment %} Bu! {% endcomment %}




    for   {% for elemento in lista %}
              <li>{{ elemento }}<li>
          {% endfor %}
Templates:	
  tags	
  {%	
  %}
comment    {% comment %} Bu! {% endcomment %}




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




      if   {% if username == "Juan" %}
               Hola Juan, me gustas!
                                                == != > < >= <=
                                                in and or not
           {% else %}
               Hola {{ username }},
           {% endif %}
Templates:	
  tags	
  {%	
  %}
Templates:	
  tags	
  {%	
  %}
cycle   {% for elemento in lista %}
            <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
        {% endfor %}
Templates:	
  tags	
  {%	
  %}
  cycle   {% for elemento in lista %}
              <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
          {% endfor %}



include   {% include "foo/bar.html" %}
Templates:	
  tags	
  {%	
  %}
  cycle   {% for elemento in lista %}
              <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
          {% endfor %}



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




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



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




forloop   {% for elemento in lista %}
              <li>{{ forloop.counter }}.{{ elemento }}<li>
          {% endfor %}



empty     {% for elemento in lista %}
              <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
          {% empty %}
              Sin elementos.
          {% endfor %}
Templates:	
  Filters
         <html>
             <head>Ejemplo templates</head>
-tle         <body>
                 Hola, {{ username|title }}.
             </body>
         </html>




               {'username': 'juan'}


         <html>
             <head>Ejemplo templates</head>
             <body>
                 Hola, Juan.
             </body>
         </html>
Templates:	
  Filters
Templates:	
  Filters
            {'username': 'Juan es majo'}


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


length    {{ username|length }}                12



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


length    {{ username|length }}                12



 cut      {{ username|cut }}                Juanesmajo



slugify   {{ username|slugify }}            juan-es-majo
Templates:	
  Filters
               {'username': 'Juan es majo'}


 length     {{ username|length }}                12



   cut      {{ username|cut }}                Juanesmajo



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



wordcount   {{ username|wordcount }}             3
Templates:	
  Filters
               {'username': 'Juan es majo'}


 length     {{ username|length }}                12



   cut      {{ username|cut }}                Juanesmajo



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



wordcount   {{ username|wordcount }}             3


 upper      {{ username|upper }}                JUAN ES MAJO
Templates:	
  Filters
                  {'username': 'Juan es majo'}


 length       {{ username|length }}                   12



   cut        {{ username|cut }}                 Juanesmajo



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



wordcount     {{ username|wordcount }}                3


 upper        {{ username|upper }}                   JUAN ES MAJO



                        {'username': None}


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



          striptags   {{ username|striptags }}



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



            striptags   {{ username|striptags }}



                        Juan es majo guapo y listo



truncatewords_html      {{ username|truncatewords_html:4 }}


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



            striptags   {{ username|striptags }}



                        Juan es majo guapo y listo



truncatewords_html      {{ username|truncatewords_html:4 }}


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



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


                        Juan es <b>majo guapo y listo</b>
Templates:	
  Filters
Templates:	
  Filters
          {'value': 123456789}


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


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



filesizeformat   {{ value|filesizeformat }}    117.7MB
Templates:	
  Filters
                       {'value': 123456789}


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



filesizeformat     {{ value|filesizeformat }}     117.7MB




 {'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }



  date          {{ date|date:”d M Y” }}        11 Sep 2010
Templates:	
  Filters
                       {'value': 123456789}


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



filesizeformat     {{ value|filesizeformat }}      117.7MB




 {'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }



  date          {{ date|date:”d M Y” }}        11 Sep 2010


-mesince        {{ date|timesince }}           4 days, 6 hours
Templates:	
  Filters
                       {'value': 123456789}


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



filesizeformat     {{ value|filesizeformat }}      117.7MB




 {'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }



  date          {{ date|date:”d M Y” }}        11 Sep 2010


-mesince        {{ date|timesince }}           4 days, 6 hours



-meun-l         {{ date|timeuntil }}           1 days, 6 hours
Herencia	
  de	
  Templates
base.html   <html>
                <head>
                    <title>Mi página personal</title>
                </head>
                <body>
                    {% block content %}
                        Contenido por defecto.
                    {% endblock %}
                </body>
            </html>




hija.html   {% extends "base.html" %}
            {% block content %}
                Hola desde la portada.
            {% endblock %}
Modelos
¿SQL?
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})
Ejemplo	
  SQL
def book_list(request):
    try:                 1
                                                     2
         db = MySQLdb.connect(user='me', db='mydb',
                                         passwd='secret', host='localhost')
    3 cursor = db.cursor()
         cursor.execute('SELECT nama FROM books ORDER BY name') 4
         names = []
        for row in cursor.fetchall() 5
             names.append(row[0])
         db.close()
    except:
        return render_to_response('500.html')
                                                6
    return render_to_response('book_list.html', {'names':names})
12	
  lineas	
  de	
  Python...	
  ¬_¬
ORM	
  (Object-­‐Rela0onal	
  mapping)
Ejemplo	
  ORM


def book_list(request):

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

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


def book_list(request):

1   names = Books.objects.all().order_by('name')
                                                                2
    return render(request, 'book_list.html', {'names':names})
Fucking	
  Ninjas!
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)	
  
Modelo
     from django.db import models                  1

                            3
2    class Books(models.Model):
           name = models.CharField(blank=True, max_length=100)                            4
           created = models.DateTimeField(blank=False)  5
           available = models.BooleanField(default=True)                            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)	
  
Fucking	
  Awesome	
  Ninjas!
Tipos	
  de	
  Datos
• AutoField                    • IPAdressField
• BigIntegerField              • NullBooleanField
• BooleanField                 • PositiveIntegerField
• CharField                    • PositiveSmallIntegerField
• CommaSeparatedIntegerField   • SlugField
• DateField                    • SmallIntegerField
• DateTimeField                • TextField
• DecimalField                 • TimeField
• EmailField                   • URLField
• FileField                    • XMLField
• FilePathField                • ForeingKey
• FloatField                   • ManyToManyField
• ImageField                   • OneToOneField
• IntegerField
Propiedades	
  de	
  las	
  Field

• null (True|Flase)       • unique (True|False)

• blank (True|False)      • primary_key
•   choices (lista)       • unique_for_date

• default (valor)         • unique_for_month

• editable (True|False)   • unique_for_year
• help_text (String)
¿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;
¿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;
Configurar	
  sesngs.py

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

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


•	
  Crea	
  las	
  tablas	
  para	
  todos	
  los	
  modelos	
  de	
  las	
  apps	
  instaladas	
  
  en	
  el	
  fichero	
  seungs.py

•	
  No	
  actualiza	
  esquemas	
  si	
  la	
  tabla	
  existe.
  •	
  Eliminar	
  tabla	
  y	
  volver	
  a	
  ejecutar	
  syncdb
Creando	
  Tablas
                $ python manage.py syncdb



•	
  Crea	
  las	
  tablas	
  para	
  todos	
  los	
  modelos	
  de	
  las	
  apps	
  instaladas	
  
  en	
  el	
  fichero	
  seungs.py

•	
  No	
  actualiza	
  esquemas	
  si	
  la	
  tabla	
  existe.
  •	
  Eliminar	
  tabla	
  y	
  volver	
  a	
  ejecutar	
  syncdb
syncdb
$ python   manage.py syncdb
Creating   table auth_permission
Creating   table auth_group
Creating   table auth_user
Creating   table auth_message
Creating   table django_content_type
Creating   table django_session
Creating   table django_site
Creating   table website_tweet

You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
syncdb
$ python   manage.py syncdb
Creating   table auth_permission
Creating   table auth_group
Creating   table auth_user                django.contrib.auth
Creating   table auth_message
Creating   table django_content_type
Creating   table django_session
Creating   table django_site
Creating   table website_tweet

You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
¿Cuantos	
  sistemas	
  de	
  Auten0cación	
  habéis	
  programado?
¿Alguno	
  era	
  mejor	
  que	
  el	
  anterior?	
  ;-­‐)
contrib.auth	
  puede	
  ser	
  el	
  úl0mo	
  :D
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           website.tweet
You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
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         django.contrib.auth
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
BD	
  Lista	
  para	
  usarse
BD	
  Lista	
  para	
  usarse
Previo:	
  Clases	
  del	
  ORM

  ts = Publisher.objects.all()


         Model

            Manager

                 QuerySet
INSERT
INSERT
             o = Model(...)    o.save()

a)   >>> p = Publisher(
     ...       name='Apress',
     ...       address='2855 Telegraph Avenue',
     ...       city='Berkeley',
     ...       state_province='CA',
     ...       country='U.S.A.',
     ...       website='http://www.apress.com/')
     >>> p.save()
INSERT
             o = Model(...)    o.save()

a)   >>> p = Publisher(
     ...       name='Apress',
     ...       address='2855 Telegraph Avenue',
     ...       city='Berkeley',
     ...       state_province='CA',
     ...       country='U.S.A.',
     ...       website='http://www.apress.com/')
     >>> p.save()



                manager.create(...)

b)   >>> p = Publisher.objects.create(
     ...       name='O'Reilly',
     ...       address='10 Fawcett St.',
     ...       city='Cambridge',
     ...       state_province='MA',
     ...       country='U.S.A.',
     ...       website='http://www.oreilly.com/')
UPDATE
UPDATE
                       o.save()

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

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




                 queryset.update(...)


n   >>> Publisher.objects.all().update(country='USA')
    2
DELETE
DELETE
                o.delete()

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

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



            queryset.delete()

    >>> ps = Publisher.objects.all()
n   >>> ps.delete()
SELECT	
  de	
  1	
  resultado
SELECT	
  de	
  1	
  resultado
                 .get(...)


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


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



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


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



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



>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
    ...
MultipleObjectsReturned: get() returned more than one Publisher --
    it returned 2! Lookup parameters were {'country': 'U.S.A.'}
SELECT	
  de	
  N	
  resultados
SELECT	
  de	
  N	
  resultados
                     .all()

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

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


                  .filter(...)

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

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


                  .filter(...)

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


                 .exclude(...)

  >>> Publisher.objects.exclude(
        country="U.S.A.", state_province="CA")
  [<Publisher: O'Reilly>]
SELECT	
  de	
  N	
  resultadosen	
  
                            evuelv        ¡D        s,	
  no	
  
                      .all()              uery  Set
                                        Q
                                             li stas!
   >>> Publisher.objects.all()
   [<Publisher: Apress>, <Publisher: O'Reilly>]


                   .filter(...)

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


                  .exclude(...)

   >>> Publisher.objects.exclude(
         country="U.S.A.", state_province="CA")
   [<Publisher: O'Reilly>]
get(),	
  filter()	
  y	
  exclude()
get(),	
  filter()	
  y	
  exclude()
 Modelo.objects.filter(campo1="valor1", campo2="valor2")


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


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



campo__exact=''              campo__gt=0             campo__startswith=''
campo__iexact=''             campo__gte=0            campo__istartswith=''
campo__contains=''           campo__lt=0             campo__endswith=''
campo__icontains=''          campo__lte=0            campo__iendswith=''
campo__isnull=T|F            campo__in=[ ,]          campo__range=( ,)
campo__day=31                campo__month=12         campo__year=2010
ORDER	
  BY
ORDER	
  BY
            .order_by(...)


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


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


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


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


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



                Múl0ples	
  campos:
>>> Publisher.objects.order_by("-name", "country")
[<Publisher: O'Reilly>, <Publisher: Apress>]
ORDER	
  BY                   ¡También	
  
                                            devu elve	
  
                  .order_by(...)
                                            uer y Sets!
                                          Q
     >>> Publisher.objects.order_by("name")
     [<Publisher: Apress>, <Publisher: O'Reilly>]


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



                Múl0ples	
  campos:
>>> Publisher.objects.order_by("-name", "country")
[<Publisher: O'Reilly>, <Publisher: Apress>]
Slicing
Slicing
                       [n:m]



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



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



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



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



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


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



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



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


>>> Publisher.objects.order_by("name")[1:2]
[<Publisher: O'Reilly>]                        O FFSET
Related	
  Objects
Related	
  Objects
          OneToOneField
     class Coche(models.Model):
1        motor = OneToOneField(Motor)


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


            class Motor(models.Model):
      1         ...



   ¿Cómo	
  usamos	
  la	
  relación	
  desde	
  las	
  instancias?

  Gracias	
  a	
  nosotros
>>> c.motor
<Motor: Motor object>
Related	
  Objects
                    OneToOneField
            class Coche(models.Model):
      1         motor = OneToOneField(Motor)


            class Motor(models.Model):
      1         ...



   ¿Cómo	
  usamos	
  la	
  relación	
  desde	
  las	
  instancias?

  Gracias	
  a	
  nosotros                   Gracias	
  a	
  Django
>>> c.motor                             >>> m.coche
<Motor: Motor object>                   <Coche: Coche object>
Related	
  Objects
Related	
  Objects
        ForeignKeyField
    class Blog(models.Model):
1       ...


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


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



     ¿Cómo	
  usamos	
  la	
  relación	
  desde	
  las	
  instancias?

  Gracias	
  a	
  nosotros                   Gracias	
  a	
  Django
>>> p.blog                           >>> b.post_set.all()
<Blog: Blog object>                  [<Post: Post object>, ...]
Related	
  Objects
Related	
  Objects
        ManyToManyField
    class Post(models.Model):
n       tags = ManyToManyField(Tag)


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


              class Tag(models.Model):
       m          ...



     ¿Cómo	
  usamos	
  la	
  relación	
  desde	
  las	
  instancias?

   Gracias	
  a	
  nosotros                   Gracias	
  a	
  Django
>>> p.tags.add(t1, t2)                 >>> t.post_set.add(p1, p2)
>>> p.tags.all()                       >>> t.post_set.all()
[<Tag: Tag object>, ...]               [<Post: Post object>, ...]
Related	
  Objects
Related	
  Objects
En	
  todas	
  ellas	
  podemos	
  renombrar	
  el	
  puntero	
  inverso
        class Blog(models.Model):
  1         ...


        class Post(models.Model):
  n         blog = ForeignKeyField(Blog, related_name='posts')
Related	
  Objects
En	
  todas	
  ellas	
  podemos	
  renombrar	
  el	
  puntero	
  inverso
         class Blog(models.Model):
  1          ...


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



      Gracias	
  a	
  nosotros             Gracias	
  a	
  Django
  >>> p.blog                         >>> b.posts.all()
  <Blog: Blog object>                [<Post: Post object>, ...]
Related	
  Objects
En	
  todas	
  ellas	
  podemos	
  renombrar	
  el	
  puntero	
  inverso
          class Blog(models.Model):
   1          ...


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



       Gracias	
  a	
  nosotros                  Gracias	
  a	
  Django
   >>> p.blog                            >>> b.posts.all()
   <Blog: Blog object>                   [<Post: Post object>, ...]



Cuando	
  haya	
  2	
  relaciones	
  entre	
  2	
  modelos,	
  será	
  obligatorio
Y	
  la	
  guinda	
  final:	
  ¡Todo	
  es	
  LAZY!
Laziness
Laziness
• Las	
  consultas	
  sólo	
  se	
  ejecutarán	
  cuando	
  realmente	
  se	
  
   necesite	
  obtener	
  los	
  objetos.	
  En	
  las	
  siguientes	
  situaciones:
      • Iteraciones               for p in Publisher.objects.all():



      • Slicing                   Publisher.objects.filter(country='USA')[0]



      • Serialización           [Caché]

      • repr()                    [<Publisher: Publisher object>]


      • len() !!!                 len(Publisher.objects.all())


      • list()                    list(Publisher.objects.all())


      • bool()                    if Publisher.objects.filter(country='USA'):
CRUD:	
  Create,	
  Retrieve,	
  Update	
  &	
  Delete
django.contrib.admin

1




            2



                 3
django.contrib.admin


      1




          2
                       3
django.contrib.admin



1
Django	
  admin:	
  Instalación
                           urls.py
    from django.conf.urls.defaults import *

    # Uncomment the next two lines to enable the admin:
    # from django.contrib import admin
  1
    # admin.autodiscover()

    urlpatterns = patterns('',

            ...

        2   # url(r'^admin/', include(admin.site.urls)),

            ...

    )
Django	
  admin:	
  Instalación
                           urls.py
    from django.conf.urls.defaults import *

    # Uncomment the next two lines to enable the admin:
    from django.contrib import admin
  1
    admin.autodiscover()

    urlpatterns = patterns('',

            ...

        2   url(r'^admin/', include(admin.site.urls)),

            ...

    )
Django	
  admin:	
  Instalación
               seungs.py

    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.admin', 1
        ...
    )
Actualizando	
  la	
  BD
Actualizando	
  la	
  BD

  $ python manage.py syncdb


 Creating table django_admin_log
 Installing index for admin.LogEntry model




           Admin	
  lista	
  para	
  usar
¿Y	
  nuestra	
  app?



      ?
¿Y	
  nuestra	
  app?
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)
1,2,3	
  Borrar	
  la	
  BD....	
  1,2,3...	
  Borrar	
  la	
  BD
Fixtures
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:
Fixtures
•	
  Es	
  muy	
  aburrido	
  crear	
  juegos	
  de	
  datos	
  cada	
  vez	
  que	
  se	
  
 elimina	
  una	
  tabla	
  /	
  BD.
•	
  No	
  nos	
  gustan	
  las	
  cosas	
  aburridas.
•	
  Ficheros	
  (json/xml/yaml)	
  para	
  inicializar	
  una	
  Tabla.
•	
  Pueden	
  crearse	
  una	
  vez	
  dispongamos	
  de	
  la	
  información:
     python manage.py dumpdata <appName appName appName.model ...>
Fixtures
•	
  Es	
  muy	
  aburrido	
  crear	
  juegos	
  de	
  datos	
  cada	
  vez	
  que	
  se	
  
 elimina	
  una	
  tabla	
  /	
  BD.
•	
  No	
  nos	
  gustan	
  las	
  cosas	
  aburridas.
•	
  Ficheros	
  (json/xml/yaml)	
  para	
  inicializar	
  una	
  Tabla.
•	
  Pueden	
  crearse	
  una	
  vez	
  dispongamos	
  de	
  la	
  información:
     python manage.py dumpdata <appName appName appName.model ...>




•	
  Se	
  cargan	
  u0lizando:
     python manage.py loaddata <fixture fixture ...>



•	
  Si	
  se	
  llaman	
  ini<al_data	
  y	
  están	
  dentro	
  de	
  la	
  carpeta	
  fixtures	
  
  de	
  la	
  app,	
  se	
  cargan	
  al	
  ahcer	
  el	
  syncdb.
Formularios
Clases	
  involucradas
Clases	
  involucradas
Widget   Componente	
  visual	
  equivalente	
  a	
  HTML
         TextInput             <input type='text'...>
         CheckboxInput         <input type='checkbox'...>
Clases	
  involucradas
Widget   Componente	
  visual	
  equivalente	
  a	
  HTML
         TextInput                 <input type='text'...>
         CheckboxInput             <input type='checkbox'...>



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



Field    Lógica	
  de	
  un	
  campo,	
  asociado	
  a	
  un	
  Widget
         EmailField
                                   widget, initial, error, ...
         IPAddressField




 Form    Conjunto	
  de	
  Fields	
  de	
  un	
  formulario
         ContactForm [nombre, email, telefono, mensaje, ...]
Fields
Fields
■ BooleanField          ■ IPAddressField
■ CharField             ■ MultipleChoiceField
■ ChoiceField           ■ NullBooleanField
■ TypedChoiceField      ■ RegexField
■ DateField             ■ SlugField
■ DateTimeField         ■ TimeField
■ DecimalField          ■ URLField
■ EmailField            ■ ComboField
■ FileField             ■ MultiValuefield
■ FilePathField         ■ SplitDateTimeField
■ FloatField            ■ ModelChoiceField
■ ImageField            ■ ModelMultipleChoiceField
■ IntegerField
Creación	
  de	
  un	
  Form
• Paso	
  1/3:	
  Definición	
  del	
  formulario	
  en	
  forms.py

    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)
Creación	
  de	
  un	
  Form
• Paso	
  2/3:	
  Maquetación	
  del	
  formulario	
  en	
  su	
  template
    <html>
    <body>
        <h1>Contact us</h1>

        {% if form.errors %}
            <p style="color: red;">
                 Please correct the error{{ form.errors|pluralize }} below.
            </p>
        {% endif %}

        <form action="" method="post">
            <table>
                {{ form.as_table }}
            </table>
            <input type="submit" value="Submit">
        </form>
    </body>
    </html>
Creación	
  de	
  un	
  Form
• Paso	
  3/3:	
  Programación	
  de	
  la	
  vista	
  en	
  views.py
    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})
Creación	
  de	
  un	
  Form
• Paso	
  3/3:	
  Programación	
  de	
  la	
  vista	
  en	
  views.py
    from django.shortcuts import render
    from mysite.contact.forms import ContactForm


    def contact(request):
         if request.method == 'POST':
                                                                   Pa _ern
             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})
Creación	
  de	
  un	
  Form
• Paso	
  3/3:	
  Programación	
  de	
  la	
  vista	
  en	
  views.py
    from django.shortcuts import render
    from mysite.contact.forms import ContactForm


    def contact(request):
         if request.method == 'POST':
                                                                   Pa _ern
             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})
Creación	
  de	
  un	
  Form
• Paso	
  3/3:	
  Programación	
  de	
  la	
  vista	
  en	
  views.py
    from django.shortcuts import render
    from mysite.contact.forms import ContactForm


    def contact(request):
         if request.method == 'POST':                              Pa _ern
             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})
Validación	
  propia
 Podemos	
  programar	
  validación	
  extra	
  asociada	
  a	
  cada	
  Field	
  
del	
  formulario	
  escribiendo	
  un	
  método	
  clean_<fieldname>:

  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
Validación	
  propia
 Podemos	
  programar	
  validación	
  extra	
  asociada	
  a	
  cada	
  Field	
  
del	
  formulario	
  escribiendo	
  un	
  método	
  clean_<fieldname>:

  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
Maquetación	
  propia
     Podemos	
  personalizar	
  la	
  maquetación	
  tanto	
  como	
  
 queramos,	
  prescindiendo	
  de	
  las	
  ayudas	
  de	
  form.as_table:

...
<form action="" method="post">
    <div class="field">
        {{ form.subject.errors }}                   Para	
  los	
  diseñadores:
        <label for="id_subject">Subject:</label>
        {{ form.subject }}                         <style type="text/css">
    </div>                                             ul.errorlist {
    <div class="field">                                     ...
        {{ form.email.errors }}                        }
        <label for="id_email">E-mail:</label>          .errorlist li {
        {{ form.email }}                                    ...
    </div>                                             }
    ...                                            </style>
    <input type="submit" value="Submit">
</form>
...
Forms	
  a	
  par0r	
  de	
  Models:	
  El	
  COLMO	
  del	
  DRY
Forms	
  a	
  par-r	
  de	
  Models
            from django.db import models


            class Author(models.Model):
models.py       name = models.CharField(max_length=100)
                birth_date = models.DateField(blank=True, null=True)
                country = models.ModelChoiceField(Country)
                ...




            from django import forms
            from books.models import Author


 forms.py   class AuthorForm(forms.ModelForm):
                class Meta:
                      model = Author
                      exclude = ('country',)
Magia	
  avanzada
ROSA
NUNCA


ROSA
NUNCA
INFRAVALORÉIS




ROSA
NUNCA
INFRAVALORÉIS
EL	
  PODER

ROSA
NUNCA
INFRAVALORÉIS
EL	
  PODER
DE	
  UN	
     PONY
ROSA
Views	
  avanzadas
                              Generic	
  Views
       Vistas	
  con	
  funcionalidad	
  genérica	
  parametrizable	
  
           mediante	
  un	
  diccionario	
  de	
  Extra	
  Op-ons



      Las	
  tuplas	
  de	
  pa>erns()	
  pueden	
  tener	
  3	
  elementos
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'}),
)
Views	
  avanzadas
    from django.views.generic.simple import direct_to_template



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



        Es	
  la	
  Generic	
  View	
  más	
  simple	
  y	
  más	
  u+lizada
Template	
  Library
Nos	
  permite	
  extender	
  el	
  sistema	
  de	
  templates	
  
        de	
  Django	
  con	
  Filters	
  y	
  Tags	
  propios
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 %}
Template	
  Library
Nos	
  permite	
  extender	
  el	
  sistema	
  de	
  templates	
  
        de	
  Django	
  con	
  Filters	
  y	
  Tags	
  propios

             Uso                                  Creación



{% load milibreria %}

...

{{ variable|mifiltro:"param" }}

...

{% mitag param1 param2 %}
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.
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()
    Ejemplo                  def cut(value, arg=' '):
                                 return value.replace(arg, '')

                             register.filter('cut', cut)
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, '')
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

 Py   thon	
                 register = template.Library()

2.4	
  se	
  hizo	
  
                             @register.filter(name='cut')
       sexy                  def cut(value, arg=' '):
                                 return value.replace(arg, '')
Custom	
  Tags
      El	
  método	
  genérico	
  para	
  crear	
  Tags	
  es	
  complejo.
Vamos	
  a	
  ver	
  cómo	
  crear	
  los	
  2	
  +pos	
  de	
  Tags	
  más	
  sencillos:

          SimpleTags                                     InclusionTags

• Son	
  inline                                 • Son	
  inline
• Reciben	
  1	
  argumento                     • Reciben	
  n	
  argumentos
• Devuelven	
  un	
  string                     • Devuelven	
  un	
  diccionario
                                                • Insertan	
  su	
  propio	
  
                                                   fragmento	
  de	
  template
SimpleTags
Ejemplo:	
  Devolver	
  la	
  hora	
  actual	
  formateada.

        {% current_time "%Y-%m-%d %I:%M %p" %}
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 ''
InclusionTags
   Ejemplo:	
  Mostar	
  anuncios	
  si	
  el	
  usuario	
  no	
  es	
  premium.

                  {% show_adverts user %}




milibreria.py




                 {% for advert in adverts %}
adverts.html         <img src='{{ advert.image }}' />
                 {% endfor %}
InclusionTags
   Ejemplo:	
  Mostar	
  anuncios	
  si	
  el	
  usuario	
  no	
  es	
  premium.

                  {% show_adverts user %}




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




                 {% for advert in adverts %}
adverts.html         <img src='{{ advert.image }}' />
                 {% endfor %}
Middleware
 Nos	
  permite	
  escribir	
  funcionalidad	
  reu0lizable	
  
que	
  se	
  inserta	
  en	
  el	
  flujo	
  de	
  ejecución	
  de	
  Django
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."""
       # ...
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',
)
Middleware
1. Sistema	
  de	
  BETA
  1. Nos	
  aseguramos	
  de	
  controlar	
  todas	
  páginas.
  2. Si	
  el	
  usuario	
  +ene	
  una	
  IP	
  o	
  un	
  User	
  o...
2. Si6o	
  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...
Internacionalización
Ofrece	
  integración	
  con	
  la	
  librería	
  GNU	
  ge>ext	
  de	
  i18n

1. Un	
  fichero	
  .pot	
  con+ene	
  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
• ¿Cómo	
  indicar	
  qué	
  strings	
  deben	
  ser	
  traducidos?




• Ges+ón	
  cómoda	
  de	
  singulares	
  y	
  plurales
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en
Introducción a Python en

Más contenido relacionado

Similar a Introducción a Python en

CIB_M03_Hacking_Phyton_CPs_ vs1.pdf
CIB_M03_Hacking_Phyton_CPs_      vs1.pdfCIB_M03_Hacking_Phyton_CPs_      vs1.pdf
CIB_M03_Hacking_Phyton_CPs_ vs1.pdffito60
 
Sesion1_Ciencia_de_Datos-Introduccion a Pithon.pdf
Sesion1_Ciencia_de_Datos-Introduccion a Pithon.pdfSesion1_Ciencia_de_Datos-Introduccion a Pithon.pdf
Sesion1_Ciencia_de_Datos-Introduccion a Pithon.pdfMarxx4
 
Programacion en python_1
Programacion en python_1Programacion en python_1
Programacion en python_1wozgeass
 
Iniciación a las artes marciales con Python
Iniciación a las artes marciales con PythonIniciación a las artes marciales con Python
Iniciación a las artes marciales con PythonIsrael Fermin Montilla
 
Programación en c++
Programación en c++Programación en c++
Programación en c++andermijan
 
Programando con Python
Programando con PythonProgramando con Python
Programando con PythonMario IC
 
Quasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en CQuasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en Cdegarden
 
INTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptx
INTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptxINTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptx
INTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptxRodmanCevallos1
 

Similar a Introducción a Python en (20)

Python workshop
Python workshopPython workshop
Python workshop
 
CIB_M03_Hacking_Phyton_CPs_ vs1.pdf
CIB_M03_Hacking_Phyton_CPs_      vs1.pdfCIB_M03_Hacking_Phyton_CPs_      vs1.pdf
CIB_M03_Hacking_Phyton_CPs_ vs1.pdf
 
Sesion1_Ciencia_de_Datos-Introduccion a Pithon.pdf
Sesion1_Ciencia_de_Datos-Introduccion a Pithon.pdfSesion1_Ciencia_de_Datos-Introduccion a Pithon.pdf
Sesion1_Ciencia_de_Datos-Introduccion a Pithon.pdf
 
Programacion en python_1
Programacion en python_1Programacion en python_1
Programacion en python_1
 
02 introduccion a python
02 introduccion a python02 introduccion a python
02 introduccion a python
 
Iniciación a las artes marciales con Python
Iniciación a las artes marciales con PythonIniciación a las artes marciales con Python
Iniciación a las artes marciales con Python
 
Go python, go
Go python, goGo python, go
Go python, go
 
Programación en c++
Programación en c++Programación en c++
Programación en c++
 
Funcional para trollear
Funcional para trollearFuncional para trollear
Funcional para trollear
 
Python
Python Python
Python
 
curso_programacion_python3.pdf
curso_programacion_python3.pdfcurso_programacion_python3.pdf
curso_programacion_python3.pdf
 
Introducción a Python
Introducción a PythonIntroducción a Python
Introducción a Python
 
Introducción a DJango
Introducción a DJangoIntroducción a DJango
Introducción a DJango
 
Programando con Python
Programando con PythonProgramando con Python
Programando con Python
 
Semana 6 Módulos en Python Entrega 2
Semana 6   Módulos en Python Entrega 2Semana 6   Módulos en Python Entrega 2
Semana 6 Módulos en Python Entrega 2
 
Viernes Tecnicos DTrace
Viernes Tecnicos DTraceViernes Tecnicos DTrace
Viernes Tecnicos DTrace
 
Quasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en CQuasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en C
 
Clase 1 - Python
Clase 1 - PythonClase 1 - Python
Clase 1 - Python
 
INTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptx
INTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptxINTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptx
INTRODUCCIÓN A LA PROGRAMACIÓN - PYTHON.pptx
 
Crackers: Tecnicas y Tacticas
Crackers: Tecnicas y Tacticas Crackers: Tecnicas y Tacticas
Crackers: Tecnicas y Tacticas
 

Más de betabeers

IONIC, el framework para crear aplicaciones híbridas multiplataforma
IONIC, el framework para crear aplicaciones híbridas multiplataformaIONIC, el framework para crear aplicaciones híbridas multiplataforma
IONIC, el framework para crear aplicaciones híbridas multiplataformabetabeers
 
Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)
Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)
Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)betabeers
 
Blockchain: la revolución industrial de internet - Oscar Lage
Blockchain: la revolución industrial de internet - Oscar LageBlockchain: la revolución industrial de internet - Oscar Lage
Blockchain: la revolución industrial de internet - Oscar Lagebetabeers
 
Cloud Learning: la formación del siglo XXI - Mónica Mediavilla
Cloud Learning: la formación del siglo XXI - Mónica MediavillaCloud Learning: la formación del siglo XXI - Mónica Mediavilla
Cloud Learning: la formación del siglo XXI - Mónica Mediavillabetabeers
 
Desarrollo web en Nodejs con Pillars por Chelo Quilón
Desarrollo web en Nodejs con Pillars por Chelo QuilónDesarrollo web en Nodejs con Pillars por Chelo Quilón
Desarrollo web en Nodejs con Pillars por Chelo Quilónbetabeers
 
La línea recta hacia el éxito - Jon Torrado - Betabeers Bilbao
La línea recta hacia el éxito -  Jon Torrado - Betabeers BilbaoLa línea recta hacia el éxito -  Jon Torrado - Betabeers Bilbao
La línea recta hacia el éxito - Jon Torrado - Betabeers Bilbaobetabeers
 
6 errores a evitar si eres una startup móvil y quieres evolucionar tu app
6 errores a evitar si eres una startup móvil y quieres evolucionar tu app6 errores a evitar si eres una startup móvil y quieres evolucionar tu app
6 errores a evitar si eres una startup móvil y quieres evolucionar tu appbetabeers
 
Dev ops.continuous delivery - Ibon Landa (Plain Concepts)
Dev ops.continuous delivery - Ibon Landa (Plain Concepts)Dev ops.continuous delivery - Ibon Landa (Plain Concepts)
Dev ops.continuous delivery - Ibon Landa (Plain Concepts)betabeers
 
Introducción a scrum - Rodrigo Corral (Plain Concepts)
Introducción a scrum - Rodrigo Corral (Plain Concepts)Introducción a scrum - Rodrigo Corral (Plain Concepts)
Introducción a scrum - Rodrigo Corral (Plain Concepts)betabeers
 
Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)
Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)
Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)betabeers
 
Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)
Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)
Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)betabeers
 
Elemental, querido Watson - Caso de Uso
Elemental, querido Watson - Caso de UsoElemental, querido Watson - Caso de Uso
Elemental, querido Watson - Caso de Usobetabeers
 
Seguridad en tu startup
Seguridad en tu startupSeguridad en tu startup
Seguridad en tu startupbetabeers
 
Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.
Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.
Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.betabeers
 
Buenas prácticas para la optimización web
Buenas prácticas para la optimización webBuenas prácticas para la optimización web
Buenas prácticas para la optimización webbetabeers
 
La magia de Scrum
La magia de ScrumLa magia de Scrum
La magia de Scrumbetabeers
 
Programador++ por @wottam
Programador++ por @wottamProgramador++ por @wottam
Programador++ por @wottambetabeers
 
RaspberryPi: Tu dispositivo para IoT
RaspberryPi: Tu dispositivo para IoTRaspberryPi: Tu dispositivo para IoT
RaspberryPi: Tu dispositivo para IoTbetabeers
 
Introducción al Big Data - Xabier Tranche - VIII Betabeers Bilbao 27/02/2015
 Introducción al Big Data - Xabier Tranche  - VIII Betabeers Bilbao 27/02/2015 Introducción al Big Data - Xabier Tranche  - VIII Betabeers Bilbao 27/02/2015
Introducción al Big Data - Xabier Tranche - VIII Betabeers Bilbao 27/02/2015betabeers
 
PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015
PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015
PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015betabeers
 

Más de betabeers (20)

IONIC, el framework para crear aplicaciones híbridas multiplataforma
IONIC, el framework para crear aplicaciones híbridas multiplataformaIONIC, el framework para crear aplicaciones híbridas multiplataforma
IONIC, el framework para crear aplicaciones híbridas multiplataforma
 
Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)
Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)
Servicios de Gestión de Datos en la Nube - Jaime Balañá (NetApp)
 
Blockchain: la revolución industrial de internet - Oscar Lage
Blockchain: la revolución industrial de internet - Oscar LageBlockchain: la revolución industrial de internet - Oscar Lage
Blockchain: la revolución industrial de internet - Oscar Lage
 
Cloud Learning: la formación del siglo XXI - Mónica Mediavilla
Cloud Learning: la formación del siglo XXI - Mónica MediavillaCloud Learning: la formación del siglo XXI - Mónica Mediavilla
Cloud Learning: la formación del siglo XXI - Mónica Mediavilla
 
Desarrollo web en Nodejs con Pillars por Chelo Quilón
Desarrollo web en Nodejs con Pillars por Chelo QuilónDesarrollo web en Nodejs con Pillars por Chelo Quilón
Desarrollo web en Nodejs con Pillars por Chelo Quilón
 
La línea recta hacia el éxito - Jon Torrado - Betabeers Bilbao
La línea recta hacia el éxito -  Jon Torrado - Betabeers BilbaoLa línea recta hacia el éxito -  Jon Torrado - Betabeers Bilbao
La línea recta hacia el éxito - Jon Torrado - Betabeers Bilbao
 
6 errores a evitar si eres una startup móvil y quieres evolucionar tu app
6 errores a evitar si eres una startup móvil y quieres evolucionar tu app6 errores a evitar si eres una startup móvil y quieres evolucionar tu app
6 errores a evitar si eres una startup móvil y quieres evolucionar tu app
 
Dev ops.continuous delivery - Ibon Landa (Plain Concepts)
Dev ops.continuous delivery - Ibon Landa (Plain Concepts)Dev ops.continuous delivery - Ibon Landa (Plain Concepts)
Dev ops.continuous delivery - Ibon Landa (Plain Concepts)
 
Introducción a scrum - Rodrigo Corral (Plain Concepts)
Introducción a scrum - Rodrigo Corral (Plain Concepts)Introducción a scrum - Rodrigo Corral (Plain Concepts)
Introducción a scrum - Rodrigo Corral (Plain Concepts)
 
Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)
Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)
Gestión de proyectos y consorcios internacionales - Iñigo Cañadas (GFI)
 
Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)
Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)
Software de gestión Open Source - Odoo - Bakartxo Aristegi (Aizean)
 
Elemental, querido Watson - Caso de Uso
Elemental, querido Watson - Caso de UsoElemental, querido Watson - Caso de Uso
Elemental, querido Watson - Caso de Uso
 
Seguridad en tu startup
Seguridad en tu startupSeguridad en tu startup
Seguridad en tu startup
 
Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.
Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.
Spark Java: Aplicaciones web ligeras y rápidas con Java, por Fran Paredes.
 
Buenas prácticas para la optimización web
Buenas prácticas para la optimización webBuenas prácticas para la optimización web
Buenas prácticas para la optimización web
 
La magia de Scrum
La magia de ScrumLa magia de Scrum
La magia de Scrum
 
Programador++ por @wottam
Programador++ por @wottamProgramador++ por @wottam
Programador++ por @wottam
 
RaspberryPi: Tu dispositivo para IoT
RaspberryPi: Tu dispositivo para IoTRaspberryPi: Tu dispositivo para IoT
RaspberryPi: Tu dispositivo para IoT
 
Introducción al Big Data - Xabier Tranche - VIII Betabeers Bilbao 27/02/2015
 Introducción al Big Data - Xabier Tranche  - VIII Betabeers Bilbao 27/02/2015 Introducción al Big Data - Xabier Tranche  - VIII Betabeers Bilbao 27/02/2015
Introducción al Big Data - Xabier Tranche - VIII Betabeers Bilbao 27/02/2015
 
PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015
PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015
PAYTPV Plataforma Integral de Cobros - VIII Betabeers Bilbao 27/02/2015
 

Introducción a Python en

  • 1. Juan Riaza @juanriaza
  • 4. Jorge  Bas0da Jaime  Irurzun me@jorgebas0da.com jaime@irurzun.com @jorgebas0da @jaimeirurzun
  • 5.
  • 6. • Legible Sintaxis  intui+va  y  estricta • Produc-vo Entre  1/3  y  1/5  más  conciso  que  Java  o  C++ • Portable GNU/Linux,  Windows,  Mac  OS  X,  ... • Extenso Standard  Library,  Third  par+es • Integrable C,  C++,  Java,  .NET,  COM,  WS,  CORBA,  ... • ...  y  Diver-do
  • 8. El  Intérprete Modo  Batch holamundo.py $ python holamundo.py #!/usr/bin/env python hola mundo! print "hola mundo!" $
  • 9. El  Intérprete Modo  Batch holamundo.py $ python holamundo.py #!/usr/bin/env python hola mundo! print "hola mundo!" $ Modo  Interac0vo $ 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!
  • 10. Tipos  de  datos object  h>p://docs.python.org/library/stdtypes.html
  • 11. Tipos  de  datos int 1234 long 35L float 3.1415 object  h>p://docs.python.org/library/stdtypes.html
  • 12. Tipos  de  datos int 1234 long 35L float 3.1415 bool True False object  h>p://docs.python.org/library/stdtypes.html
  • 13. Tipos  de  datos int 1234 long 35L float 3.1415 bool True False str 'spam' "guido's" """n lines""" object  h>p://docs.python.org/library/stdtypes.html
  • 14. Tipos  de  datos int 1234 long 35L float 3.1415 bool True False str 'spam' "guido's" """n lines""" object list [1, [2, 'three'], 4]  h>p://docs.python.org/library/stdtypes.html
  • 15. Tipos  de  datos int 1234 long 35L float 3.1415 bool True False str 'spam' "guido's" """n lines""" object list [1, [2, 'three'], 4] dict {'food': 'spam', 'taste': 'yum'}  h>p://docs.python.org/library/stdtypes.html
  • 16. Tipos  de  datos int 1234 long 35L float 3.1415 bool True False str 'spam' "guido's" """n lines""" object list [1, [2, 'three'], 4] dict {'food': 'spam', 'taste': 'yum'} tuple (1, 'spam', 4, 'U')  h>p://docs.python.org/library/stdtypes.html
  • 17. Tipos  de  datos o   ¡T i p ad mi co! int 1234 long 35L float d iná 3.1415 bool True False str 'spam' "guido's" """n lines""" object list [1, [2, 'three'], 4] dict {'food': 'spam', 'taste': 'yum'} tuple (1, 'spam', 4, 'U')  h>p://docs.python.org/library/stdtypes.html
  • 19. Operadores a + b a - b a * b a / b numéricos a % b -a +a a ** b  h>p://docs.python.org/library/operator.html
  • 20. Operadores a + b a - b a * b a / b numéricos a % b -a +a a ** b a < b a <= b a > b comparadores a >= b a == b a != b  h>p://docs.python.org/library/operator.html
  • 21. Operadores a + b a - b a * b a / b numéricos a % b -a +a a ** b a < b a <= b a > b comparadores a >= b a == b a != b lógicos a or b a and b not a  h>p://docs.python.org/library/operator.html
  • 23. Usos  frecuentes:  list >>> nums = [1, 2, 3] >>> nums[0] 1
  • 24. Usos  frecuentes:  list >>> nums = [1, 2, 3] >>> nums[0] 1 >>> 2 in nums True
  • 25. Usos  frecuentes:  list >>> nums = [1, 2, 3] >>> nums[0] 1 >>> 2 in nums True >>> nums.append(4) >>> print nums [1, 2, 3, 4]
  • 26. Usos  frecuentes:  list >>> nums = [1, 2, 3] >>> nums[0] 1 >>> 2 in nums True >>> nums.append(4) >>> print nums [1, 2, 3, 4] >>> len(nums) 4
  • 28. Usos  frecuentes:  str >>> "Python mola"[1:4] 'yth'
  • 29. Usos  frecuentes:  str >>> "Python mola"[1:4] 'yth' >>> "Python mola".find("mola") 7
  • 30. Usos  frecuentes:  str >>> "Python mola"[1:4] 'yth' >>> "Python mola".find("mola") 7 >>> "Python mola".replace("Python", "PHP no") 'PHP no mola'
  • 31. 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']
  • 32. 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"
  • 34. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24} >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24]
  • 35. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24} >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24] >>> user['age'] >>> user.get('age', 20) 24 24
  • 36. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24} >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24] >>> user['age'] >>> user.get('age', 20) 24 24 >>> 'nick' in user True
  • 37. Usos  frecuentes:  dict >>> user = {'nick': 'neo', 'age': 24} >>> user.keys() ['nick', 'age'] >>> user.values() ['neo', 24] >>> user['age'] >>> user.get('age', 20) 24 24 >>> 'nick' in user True >>> user.update({'nick': 'alatar', 'age': 25}) >>> user {'nick': 'alatar', 'age': 25}
  • 39. Usos  frecuentes:  str  % >>> "%s es muy sabio" % "Hycker" 'Hycker es muy sabio'
  • 40. Usos  frecuentes:  str  % >>> "%s es muy sabio" % "Hycker" 'Hycker es muy sabio' >>> "%s sabe %i idiomas" % ("Hycker", 5) 'Hycker sabe 5 idiomas'
  • 41. 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'
  • 42. Módulos juego/ __init__.py 1. Un  módulo  es  un  fichero  .py bonus/ __init__.py estrella.py moneda.py 2. Los  módulos  pueden   planta.py ... personajes/ organizarse  en  paquetes. __init__.py mario.py luigi.py princesa.py 3. Un  paquete  es  una  carpeta   ... enemigos/ __init__.py que  con+ene  un  fichero  con   seta.py tortuga.py nombre  __init__.py bomba.py ...
  • 43. Módulos juego/ __init__.py 1. Un  módulo  es  un  fichero  .py bonus/ __init__.py estrella.py moneda.py 1 2. Los  módulos  pueden   planta.py 2 ... personajes/ organizarse  en  paquetes. __init__.py 3 mario.py luigi.py princesa.py 3. Un  paquete  es  una  carpeta   ... enemigos/ __init__.py que  con+ene  un  fichero  con   seta.py tortuga.py nombre  __init__.py bomba.py ...
  • 44. 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 ...
  • 45. Módulos juego/ __init__.py bonus/ __init__.py >>> from juego.personajes.mario import Mario estrella.py >>> Mario() moneda.py planta.py ... personajes/ __init__.py >>> from juego.personajes.mario import * mario.py >>> Mario() luigi.py princesa.py ... enemigos/ >>> from juego import personajes __init__.py >>> personajes.mario.Mario() seta.py tortuga.py bomba.py ...
  • 48. Identación >>> from __future__ import braces File "<stdin>", line 1 SyntaxError: not a chance 4  Espacios  para  la  identación
  • 49. Identación >>> from __future__ import braces File "<stdin>", line 1 SyntaxError: not a chance PEP 8 4  Espacios  para  la  identación
  • 50. ¿PEP  8? PEP 8 •  Guido  van  Rossum  (2001) •  Recomendaciones  de  es0lo •  “Readability  counts” •  “Code  is  read  much  more  oQen  than  it  is  wriSen.” •  Muy  recomendable  importante  seguirlo.  h>p://www.python.org/dev/peps/pep-­‐0008/
  • 51. Funciones def my_first_function(p1, p2): return "Hello World!" Minúsculas Palabras  separadas  por  _ Evitar  camelCase
  • 52. Funciones 2 1 def my_first_function(p1, p2): 3 return "Hello World!" PEP 8 Minúsculas Palabras  separadas  por  _ Evitar  camelCase
  • 53. Conversión  de  -pos  h>p://docs.python.org/library/func-ons.html
  • 54. Conversión  de  -pos >>> int(1.3) 1  h>p://docs.python.org/library/func-ons.html
  • 55. Conversión  de  -pos >>> int(1.3) 1 >>> str(2) '2'  h>p://docs.python.org/library/func-ons.html
  • 56. Conversión  de  -pos >>> int(1.3) 1 >>> str(2) '2' >>> float(1) 1.0  h>p://docs.python.org/library/func-ons.html
  • 57. Conversión  de  -pos >>> int(1.3) 1 >>> tuple([1,2,3]) (1, 2, 3) >>> str(2) '2' >>> float(1) 1.0  h>p://docs.python.org/library/func-ons.html
  • 58. Conversión  de  -pos >>> int(1.3) 1 >>> tuple([1,2,3]) (1, 2, 3) >>> str(2) '2' >>> list((1,2,3)) [1, 2, 3] >>> float(1) 1.0  h>p://docs.python.org/library/func-ons.html
  • 59. Funciones  comunes  h>p://docs.python.org/library/func-ons.html
  • 60. Funciones  comunes >>> len("Python Mola") 11 >>> len([1,2,3,4]) 4  h>p://docs.python.org/library/func-ons.html
  • 61. 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
  • 62. Funciones  comunes >>> type(True) >>> len("Python Mola") <type 'bool'> 11 >>> type("Python Mola") >>> len([1,2,3,4]) <type 'str'> 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
  • 63. Funciones  comunes >>> type(True) >>> len("Python Mola") <type 'bool'> 11 >>> type("Python Mola") >>> len([1,2,3,4]) <type 'str'> 4 >>> range(5) >>> sum([0,1,2,3,4]) [0, 1, 2, 3, 4] 10 >>> range(1,7) >>> sum(range(5)) [1, 2, 3, 4, 5, 6] 10 >>> range(1,7,2) [1, 3, 5] Y  un  muy  largo  etc...  h>p://docs.python.org/library/func-ons.html
  • 64. Funciones  interesantes Son  sólo  un  ejemplo...  h>p://docs.python.org/library/func-ons.html
  • 65. 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
  • 66. 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
  • 67. Funciones  interesantes >>> a = [1,2,3] >>> b = [4,5,6] >>> round(1.2345, 2) >>> zip(a,b) 1.23 [(1, 4), (2, 5), (3, 6)] >>> sorted([5,1,3,4,2]) [1, 2, 3, 4, 5] Son  sólo  un  ejemplo...  h>p://docs.python.org/library/func-ons.html
  • 68. Funciones  interesantes >>> a = [1,2,3] >>> b = [4,5,6] >>> round(1.2345, 2) >>> zip(a,b) 1.23 [(1, 4), (2, 5), (3, 6)] >>> sorted([5,1,3,4,2]) >>> map(str,[1,2,3,4,5]) [1, 2, 3, 4, 5] ['1', '2', '3', '4', '5'] Son  sólo  un  ejemplo...  h>p://docs.python.org/library/func-ons.html
  • 70. 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']
  • 71. 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)
  • 72. Clases class Student(object): def __init__(self, name, age): self.name = name self.age = age def hello(self): return 'My name is %s' % self.name s = Student("Jorge", 24) camelCase
  • 73. Clases 1 2 class Student(object): 3 def __init__(self, name, age): 4 self.name = name self.age = age def hello(self): 5 return 'My name is %s' % self.name s = Student("Jorge", 24) PEP 8 camelCase
  • 74. El  operador  () • Es  importante  diferenciar: funcion      vs      funcion() Clase              vs        Clase() • El  operador  ()  permite: • Invocar  funciones: resultado = funcion() • Instanciar  clases: objeto = Clase("param1")
  • 75. Sentencias:  if-­‐else $name = "Jon"; name = "Jon" if($name == "Jon"){ if name == "Jon": $name = "Jon Rocks!"; name = "Jon Rocks!" } elif name == "Mary": elseif($name == "Mary"){ name = "Hello Mary" $name = "Hello Mary"; else: } name = "Who are you?" else{ $name = "Who are you?" }
  • 76. Sentencias:  while $count = 0; while ($count < 5) { echo "Number ".$count; $count+=1; } count = 0 while count < 5: print "Number %i" % count count+=1
  • 77. Sentencias:  for for ($i=0; $i < 5; $i++) { echo "Number ".$count; } for i in range(4): print "Number %i" % count
  • 78. Sentencias:  try-­‐except try { $result = 3 / 0; } catch (Exception $e) { echo "Division by Zero" } try: result = 3 / 0 except: print "Division by Zero"
  • 79. Conclusiones •  Python  es  un  lenguaje  fácil  de  aprender. •  Menos  código: •  Muchos  Muchísimos  menos  errores  de  Sintaxis. •  Mayor  velocidad  de  escritura. •  Proto0pado...  U0lizado  por  grandes  empresas.
  • 80. Conclusiones •  Python  es  un  lenguaje  fácil  de  aprender. •  Menos  código: •  Muchos  Muchísimos  menos  errores  de  Sintaxis. •  Mayor  velocidad  de  escritura. •  Proto0pado...  U0lizado  por  grandes  empresas. etc...
  • 81.
  • 82. Evolución  de  la  Web Desarrollo  Web 1ª  Generación 2ª  Generación 3ª  Generación HTML PHP Django CGI ASP Rails JSP Symfony ... ...
  • 84. Django:  Qué  y  dónde
  • 85. Filosoa •  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)
  • 86. Filosoa •  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.”
  • 87. Filosoa •  Explicit  is  beSer  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.  h>p://docs.djangoproject.com/en/dev/misc/design-­‐philosophies/
  • 89. La  comunidad • django-­‐users 22.000  miembros • django-­‐developers 7.000  miembros • djangoproject.com +500.000  visitas  únicas  mensuales
  • 92.
  • 94. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? *  Incluida  la  carpeta  del  proyecto
  • 95. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Ficheros Carpetas *  Incluida  la  carpeta  del  proyecto
  • 96. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Rails Symfony Ficheros 149 117 Carpetas 35 29 *  Incluida  la  carpeta  del  proyecto
  • 97. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Rails Symfony Ficheros 149 117 Carpetas 35 29 *  Incluida  la  carpeta  del  proyecto
  • 98. Ficheros  y  Carpetas ¿Es  Django  tán  simple  y  fácil  de  usar? Rails Symfony Django Ficheros 149 117 5 Carpetas 35 29 2 *  Incluida  la  carpeta  del  proyecto
  • 100. Crear  nuestro  proyecto de  5  ficheros  ;-­‐)
  • 101. Crear  nuestro  proyecto de  5  ficheros  ;-­‐) $ django-admin startproject dwitter
  • 102. Crear  nuestro  proyecto de  5  ficheros  ;-­‐) $ django-admin startproject dwitter . !"" dwitter #   !"" __init__.py #   !"" settings.py #   !"" urls.py #   $"" wsgi.py $"" manage.py -­‐  ¿Esto  es  un  proyecto...  ?      Si  os  ve  mi  jefe... -­‐  Sí,  disponemos  de  un  proyecto  ‘funcional’  en  django.
  • 104. Arrancar  nuestro  proyecto de  5  ficheros  ;-­‐)
  • 105. 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.
  • 106. 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.
  • 107. MVC  en  Django Modelo  =  Model Vista  =  Template Controlador  =  URL+View
  • 108. URLs  y  Vistas • El  fichero  urls.py  actúa  como  puerta  de  entrada  para  las   pe0ciones  HTTP • Se  definen  URLs  elegantes  mediante  expresiones  regulares   que  redirigen  a  funciones  de  views.py hSp://mysite.com/about/ urls.py ¿urlpaSerns? html views.py ...
  • 109. 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 H>pRequest(),  ... views.py H>pResponse()
  • 110. URLs  y  Vistas Ejemplo  1:    http://mysite.com/time from django.conf.urls.defaults import * from mysite.views import hora_actual urls.py urlpatterns = patterns('', url(r'^time/$', hora_actual), ) from django.http import HttpResponse from datetime import datetime views.py def hora_actual(request): now = datetime.now() html = "Son las %s." % now return HttpResponse(html)
  • 111. URLs  y  Vistas Ejemplo  2:    http://mysite.com/time/plus/2 from django.conf.urls.defaults import * from mysite.views import dentro_de urls.py urlpatterns = patterns('', url(r'^time/plus/(d{1,2})/$', dentro_de), ) from django.http import HttpResponse from datetime import datetime, timedelta def dentro_de(request, offset): views.py offset = int(offset) dt = datetime.now() + timedelta(hours=offset) html = "En %i hora(s), serán las %s." % (offset, dt) return HttpResponse(html)
  • 112.
  • 113. URLs  y  Vistas Ejemplo  2:    http://mysite.com/time/plus/2 from django.conf.urls.defaults import * from mysite.views import dentro_de urls.py urlpatterns = patterns('', url(r'^time/plus/(d{1,2})/$', dentro_de), ) from django.http import HttpResponse from datetime import datetime, timedelta def dentro_de(request, offset): views.py offset = int(offset) dt = datetime.now() + timedelta(hours=offset) html = "En %i hora(s), serán las %s." % (offset, dt) return HttpResponse(html)
  • 115. Templates • Separan  la  lógica  de  presentación  a  una  capa  independiente. • Ficheros  independientes  (.html) • Lenguaje  independiente  (¡para  diseñadores!)
  • 116. Templates • Se  basan  en  dos  0pos  de  objetos:  Template()  y  Context(). • Un  objeto  Template()  con0ene  el  string  de  salida  que   queremos  devolver  en  el  HSpResponse  (normalmente   HTML),  pero  incluyendo  e0quetas  especiales  de  Django. • Un  objeto  Context()  con0ene  un  diccionario  con  los   valores  que  dan  contexto  a  una  plan0lla,  los  que  deben   usarse  para  renderizar  un  objeto  Template(). Template: "Bienvenido, {{ user }}." "Bienvenido, alatar." Context: {'user': 'alatar'}
  • 117. Templates • Primera  aproximación  al  obje0vo:  Template  +  Context from django.http import HttpResponse from django.template import Template, Context from datetime import datetime PLANTILLA = """<html><body> Son las {{ hora }}. </body></html>""" def hora_actual(request): now = datetime.now() t = Template(PLANTILLA) c = Context({'hora': now}) html = t.render(c) return HttpResponse(html)
  • 118. Templates • Segunda  aproximación  al  obje0vo:  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)
  • 119. Templates • Segunda  aproximación  al  obje0vo:  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)
  • 120. Templates • Segunda  aproximación  al  obje0vo:  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() Bo ring   plate   fp = open('/home/django/templates/hora.html') boiler t = Template(fp.read()) fp.close() code! c = Context({'hora': now}) html = t.render(c) return HttpResponse(html)
  • 121. Templates • Tercera  aproximación  al  obje0vo:  get_template() TEMPLATE_DIRS = ( seungs.py '/home/django/templates', ) from django.http import HttpResponse from django.template.loader import get_template from django.template import Context from datetime import datetime def hora_actual(request): now = datetime.now() t = get_template('hora.html') c = Context({'hora': now}) html = t.render(c) return HttpResponse(html)
  • 122. Templates • Tercera  aproximación  al  obje0vo:  get_template() TEMPLATE_DIRS = ( seungs.py '/home/django/templates', ) from django.http import HttpResponse from django.template.loader import get_template from django.template import Context from datetime import datetime def hora_actual(request): now = datetime.now() t = get_template('hora.html') c = Context({'hora': now}) html = t.render(c) return HttpResponse(html)
  • 123. Templates • Tercera  aproximación  al  obje0vo:  get_template() TEMPLATE_DIRS = ( seungs.py '/home/django/templates', ) from django.http import HttpResponse from django.template.loader import get_template from django.template import Context from datetime import datetime def hora_actual(request): S0ll   now = datetime.now() t = get_template('hora.html') c = Context({'hora': now}) html = t.render(c) boring... return HttpResponse(html)
  • 124. Templates • Obje0vo  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})
  • 125. Templates • Obje0vo  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}) Bori ng...?
  • 126. Templates • Obje0vo  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!
  • 127. 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
  • 128. Filosoa  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.
  • 129. Templates:  {{}} <html> <head>Ejemplo templates</head> <body> Hola, {{ username }}. </body> </html> {'username': 'juan'} <html> <head>Ejemplo templates</head> <body> Hola, juan. </body> </html>
  • 132. Filters  y  Tags filter {{ varible|filter }}
  • 133. Filters  y  Tags filter {{ varible|filter }} inline  tag {% tag var1 var2 %}
  • 134. Filters  y  Tags filter {{ varible|filter }} inline  tag {% tag var1 var2 %} block  tag {% tag var1 %} ... {% endtag %}
  • 136. Templates:  tags  {%  %} comment {% comment %} Bu! {% endcomment %}
  • 137. Templates:  tags  {%  %} comment {% comment %} Bu! {% endcomment %} for {% for elemento in lista %} <li>{{ elemento }}<li> {% endfor %}
  • 138. Templates:  tags  {%  %} comment {% comment %} Bu! {% endcomment %} for {% for elemento in lista %} <li>{{ elemento }}<li> {% endfor %} if {% if username == "Juan" %} Hola Juan, me gustas! == != > < >= <= in and or not {% else %} Hola {{ username }}, {% endif %}
  • 140. Templates:  tags  {%  %} cycle {% for elemento in lista %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% endfor %}
  • 141. Templates:  tags  {%  %} cycle {% for elemento in lista %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% endfor %} include {% include "foo/bar.html" %}
  • 142. Templates:  tags  {%  %} cycle {% for elemento in lista %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% endfor %} include {% include "foo/bar.html" %} forloop {% for elemento in lista %} <li>{{ forloop.counter }}.{{ elemento }}<li> {% endfor %}
  • 143. Templates:  tags  {%  %} cycle {% for elemento in lista %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% endfor %} include {% include "foo/bar.html" %} forloop {% for elemento in lista %} <li>{{ forloop.counter }}.{{ elemento }}<li> {% endfor %} empty {% for elemento in lista %} <li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li> {% empty %} Sin elementos. {% endfor %}
  • 144. Templates:  Filters <html> <head>Ejemplo templates</head> -tle <body> Hola, {{ username|title }}. </body> </html> {'username': 'juan'} <html> <head>Ejemplo templates</head> <body> Hola, Juan. </body> </html>
  • 146. Templates:  Filters {'username': 'Juan es majo'} length {{ username|length }} 12
  • 147. Templates:  Filters {'username': 'Juan es majo'} length {{ username|length }} 12 cut {{ username|cut }} Juanesmajo
  • 148. Templates:  Filters {'username': 'Juan es majo'} length {{ username|length }} 12 cut {{ username|cut }} Juanesmajo slugify {{ username|slugify }} juan-es-majo
  • 149. Templates:  Filters {'username': 'Juan es majo'} length {{ username|length }} 12 cut {{ username|cut }} Juanesmajo slugify {{ username|slugify }} juan-es-majo wordcount {{ username|wordcount }} 3
  • 150. Templates:  Filters {'username': 'Juan es majo'} length {{ username|length }} 12 cut {{ username|cut }} Juanesmajo slugify {{ username|slugify }} juan-es-majo wordcount {{ username|wordcount }} 3 upper {{ username|upper }} JUAN ES MAJO
  • 151. Templates:  Filters {'username': 'Juan es majo'} length {{ username|length }} 12 cut {{ username|cut }} Juanesmajo slugify {{ username|slugify }} juan-es-majo wordcount {{ username|wordcount }} 3 upper {{ username|upper }} JUAN ES MAJO {'username': None} default {{ username|default:”Desconocido” }} Desconocido
  • 153. Templates:  Filters {'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'} striptags {{ username|striptags }} Juan es majo guapo y listo
  • 154. Templates:  Filters {'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'} striptags {{ username|striptags }} Juan es majo guapo y listo truncatewords_html {{ username|truncatewords_html:4 }} Juan es <b>majo guapo</b> ...
  • 155. Templates:  Filters {'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'} striptags {{ username|striptags }} Juan es majo guapo y listo truncatewords_html {{ username|truncatewords_html:4 }} Juan es <b>majo guapo</b> ... removetags {{ username|removetags:”em a br” }} Juan es <b>majo guapo y listo</b>
  • 157. Templates:  Filters {'value': 123456789} add {{ value|add:”1” }} 123456790
  • 158. Templates:  Filters {'value': 123456789} add {{ value|add:”1” }} 123456790 filesizeformat {{ value|filesizeformat }} 117.7MB
  • 159. Templates:  Filters {'value': 123456789} add {{ value|add:”1” }} 123456790 filesizeformat {{ value|filesizeformat }} 117.7MB {'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) } date {{ date|date:”d M Y” }} 11 Sep 2010
  • 160. Templates:  Filters {'value': 123456789} add {{ value|add:”1” }} 123456790 filesizeformat {{ value|filesizeformat }} 117.7MB {'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) } date {{ date|date:”d M Y” }} 11 Sep 2010 -mesince {{ date|timesince }} 4 days, 6 hours
  • 161. Templates:  Filters {'value': 123456789} add {{ value|add:”1” }} 123456790 filesizeformat {{ value|filesizeformat }} 117.7MB {'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) } date {{ date|date:”d M Y” }} 11 Sep 2010 -mesince {{ date|timesince }} 4 days, 6 hours -meun-l {{ date|timeuntil }} 1 days, 6 hours
  • 162. Herencia  de  Templates base.html <html> <head> <title>Mi página personal</title> </head> <body> {% block content %} Contenido por defecto. {% endblock %} </body> </html> hija.html {% extends "base.html" %} {% block content %} Hola desde la portada. {% endblock %}
  • 164. ¿SQL?
  • 165. 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})
  • 166. Ejemplo  SQL def book_list(request): try: 1 2 db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost') 3 cursor = db.cursor() cursor.execute('SELECT nama FROM books ORDER BY name') 4 names = [] for row in cursor.fetchall() 5 names.append(row[0]) db.close() except: return render_to_response('500.html') 6 return render_to_response('book_list.html', {'names':names})
  • 167. 12  lineas  de  Python...  ¬_¬
  • 169. Ejemplo  ORM def book_list(request): names = Books.objects.all().order_by('name') return render(request, 'book_list.html', {'names':names})
  • 170. Ejemplo  ORM def book_list(request): 1 names = Books.objects.all().order_by('name') 2 return render(request, 'book_list.html', {'names':names})
  • 172. 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)  
  • 173. Modelo from django.db import models 1 3 2 class Books(models.Model): name = models.CharField(blank=True, max_length=100) 4 created = models.DateTimeField(blank=False) 5 available = models.BooleanField(default=True) 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)  
  • 175. Tipos  de  Datos • AutoField • IPAdressField • BigIntegerField • NullBooleanField • BooleanField • PositiveIntegerField • CharField • PositiveSmallIntegerField • CommaSeparatedIntegerField • SlugField • DateField • SmallIntegerField • DateTimeField • TextField • DecimalField • TimeField • EmailField • URLField • FileField • XMLField • FilePathField • ForeingKey • FloatField • ManyToManyField • ImageField • OneToOneField • IntegerField
  • 176. Propiedades  de  las  Field • null (True|Flase) • unique (True|False) • blank (True|False) • primary_key • choices (lista) • unique_for_date • default (valor) • unique_for_month • editable (True|False) • unique_for_year • help_text (String)
  • 177. ¿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;
  • 178. ¿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;
  • 179. Configurar  sesngs.py DATABASES = { 'default': { 'postgresql_psycopg2', 'ENGINE': 'django.db.backends.', 'postgresql', 'mysql', 'NAME': '', 'sqlite3' or 'oracle'. 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } }
  • 180. Configurar  sesngs.py DATABASES = { 'default': { 'postgresql_psycopg2', 'ENGINE': 'django.db.backends.', 1 'postgresql', 'mysql', 'NAME': '', 2 'sqlite3' or 'oracle'. 'USER': '', 'PASSWORD': '', 3 'HOST': '', 'PORT': '', } }
  • 181. Creando  Tablas •  Crea  las  tablas  para  todos  los  modelos  de  las  apps  instaladas   en  el  fichero  seungs.py •  No  actualiza  esquemas  si  la  tabla  existe. •  Eliminar  tabla  y  volver  a  ejecutar  syncdb
  • 182. Creando  Tablas $ python manage.py syncdb •  Crea  las  tablas  para  todos  los  modelos  de  las  apps  instaladas   en  el  fichero  seungs.py •  No  actualiza  esquemas  si  la  tabla  existe. •  Eliminar  tabla  y  volver  a  ejecutar  syncdb
  • 183. syncdb $ python manage.py syncdb Creating table auth_permission Creating table auth_group Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating table website_tweet You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model
  • 184. syncdb $ python manage.py syncdb Creating table auth_permission Creating table auth_group Creating table auth_user django.contrib.auth Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating table website_tweet You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model
  • 185. ¿Cuantos  sistemas  de  Auten0cación  habéis  programado?
  • 186. ¿Alguno  era  mejor  que  el  anterior?  ;-­‐)
  • 187. contrib.auth  puede  ser  el  úl0mo  :D
  • 188. 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 website.tweet You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (Leave blank to use 'neo'): admin E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model
  • 189. 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 django.contrib.auth E-mail address: user@example.com Password: Password (again): Superuser created successfully. Installing index for auth.Permission model Installing index for auth.Message model Installing index for website.Tweet model
  • 190. BD  Lista  para  usarse
  • 191. BD  Lista  para  usarse
  • 192.
  • 193. Previo:  Clases  del  ORM ts = Publisher.objects.all() Model Manager QuerySet
  • 194. INSERT
  • 195. INSERT o = Model(...) o.save() a) >>> p = Publisher( ... name='Apress', ... address='2855 Telegraph Avenue', ... city='Berkeley', ... state_province='CA', ... country='U.S.A.', ... website='http://www.apress.com/') >>> p.save()
  • 196. INSERT o = Model(...) o.save() a) >>> p = Publisher( ... name='Apress', ... address='2855 Telegraph Avenue', ... city='Berkeley', ... state_province='CA', ... country='U.S.A.', ... website='http://www.apress.com/') >>> p.save() manager.create(...) b) >>> p = Publisher.objects.create( ... name='O'Reilly', ... address='10 Fawcett St.', ... city='Cambridge', ... state_province='MA', ... country='U.S.A.', ... website='http://www.oreilly.com/')
  • 197. UPDATE
  • 198. UPDATE o.save() >>> ... >>> p.id 1 52 >>> p.name = 'Apress Publishing' >>> p.save()
  • 199. UPDATE o.save() >>> ... >>> p.id 1 52 >>> p.name = 'Apress Publishing' >>> p.save() queryset.update(...) n >>> Publisher.objects.all().update(country='USA') 2
  • 200. DELETE
  • 201. DELETE o.delete() >>> ... >>> p.id 1 52 >>> p.delete()
  • 202. DELETE o.delete() >>> ... >>> p.id 1 52 >>> p.delete() queryset.delete() >>> ps = Publisher.objects.all() n >>> ps.delete()
  • 203. SELECT  de  1  resultado
  • 204. SELECT  de  1  resultado .get(...) >>> Publisher.objects.get(name="Apress") <Publisher: Apress>
  • 205. SELECT  de  1  resultado .get(...) >>> Publisher.objects.get(name="Apress") <Publisher: Apress> >>> Publisher.objects.get(name="Anaya") Traceback (most recent call last): ... DoesNotExist: Publisher matching query does not exist.
  • 206. SELECT  de  1  resultado .get(...) >>> Publisher.objects.get(name="Apress") <Publisher: Apress> >>> Publisher.objects.get(name="Anaya") Traceback (most recent call last): ... DoesNotExist: Publisher matching query does not exist. >>> Publisher.objects.get(country="U.S.A.") Traceback (most recent call last): ... MultipleObjectsReturned: get() returned more than one Publisher -- it returned 2! Lookup parameters were {'country': 'U.S.A.'}
  • 207. SELECT  de  N  resultados
  • 208. SELECT  de  N  resultados .all() >>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>]
  • 209. SELECT  de  N  resultados .all() >>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>] .filter(...) >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [<Publisher: Apress>]
  • 210. SELECT  de  N  resultados .all() >>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>] .filter(...) >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [<Publisher: Apress>] .exclude(...) >>> Publisher.objects.exclude( country="U.S.A.", state_province="CA") [<Publisher: O'Reilly>]
  • 211. SELECT  de  N  resultadosen   evuelv ¡D s,  no   .all() uery Set Q li stas! >>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>] .filter(...) >>> Publisher.objects.filter( country="U.S.A.", state_province="CA") [<Publisher: Apress>] .exclude(...) >>> Publisher.objects.exclude( country="U.S.A.", state_province="CA") [<Publisher: O'Reilly>]
  • 212. get(),  filter()  y  exclude()
  • 213. get(),  filter()  y  exclude() Modelo.objects.filter(campo1="valor1", campo2="valor2") Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=)
  • 214. get(),  filter()  y  exclude() Modelo.objects.filter(campo1="valor1", campo2="valor2") Los  parámetros  pueden  indicar  mucho  más  que  igualdad  (=) campo__exact='' campo__gt=0 campo__startswith='' campo__iexact='' campo__gte=0 campo__istartswith='' campo__contains='' campo__lt=0 campo__endswith='' campo__icontains='' campo__lte=0 campo__iendswith='' campo__isnull=T|F campo__in=[ ,] campo__range=( ,) campo__day=31 campo__month=12 campo__year=2010
  • 216. ORDER  BY .order_by(...) >>> Publisher.objects.order_by("name") [<Publisher: Apress>, <Publisher: O'Reilly>]
  • 217. ORDER  BY .order_by(...) >>> Publisher.objects.order_by("name") [<Publisher: Apress>, <Publisher: O'Reilly>] >>> Publisher.objects.order_by("-name") [<Publisher: O'Reilly>, <Publisher: Apress>]
  • 218. ORDER  BY .order_by(...) >>> Publisher.objects.order_by("name") [<Publisher: Apress>, <Publisher: O'Reilly>] >>> Publisher.objects.order_by("-name") [<Publisher: O'Reilly>, <Publisher: Apress>] Múl0ples  campos: >>> Publisher.objects.order_by("-name", "country") [<Publisher: O'Reilly>, <Publisher: Apress>]
  • 219. ORDER  BY ¡También   devu elve   .order_by(...) uer y Sets! Q >>> Publisher.objects.order_by("name") [<Publisher: Apress>, <Publisher: O'Reilly>] >>> Publisher.objects.order_by("-name") [<Publisher: O'Reilly>, <Publisher: Apress>] Múl0ples  campos: >>> Publisher.objects.order_by("-name", "country") [<Publisher: O'Reilly>, <Publisher: Apress>]
  • 221. Slicing [n:m] >>> Publisher.objects.order_by("name")[0] <Publisher: Apress> >>> Publisher.objects.order_by("name")[:2] [<Publisher: Apress>, <Publisher: O'Reilly>] >>> Publisher.objects.order_by("name")[1:2] [<Publisher: O'Reilly>]
  • 222. Slicing [n:m] >>> Publisher.objects.order_by("name")[0] <Publisher: Apress> >>> Publisher.objects.order_by("name")[:2] [<Publisher: Apress>, <Publisher: O'Reilly>] LIMIT >>> Publisher.objects.order_by("name")[1:2] [<Publisher: O'Reilly>]
  • 223. Slicing [n:m] >>> Publisher.objects.order_by("name")[0] <Publisher: Apress> >>> Publisher.objects.order_by("name")[:2] [<Publisher: Apress>, <Publisher: O'Reilly>] LIMIT >>> Publisher.objects.order_by("name")[1:2] [<Publisher: O'Reilly>] O FFSET
  • 225. Related  Objects OneToOneField class Coche(models.Model): 1 motor = OneToOneField(Motor) class Motor(models.Model): 1 ...
  • 226. Related  Objects OneToOneField class Coche(models.Model): 1 motor = OneToOneField(Motor) class Motor(models.Model): 1 ... ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros >>> c.motor <Motor: Motor object>
  • 227. Related  Objects OneToOneField class Coche(models.Model): 1 motor = OneToOneField(Motor) class Motor(models.Model): 1 ... ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django >>> c.motor >>> m.coche <Motor: Motor object> <Coche: Coche object>
  • 229. Related  Objects ForeignKeyField class Blog(models.Model): 1 ... class Post(models.Model): n blog = ForeignKeyField(Blog)
  • 230. Related  Objects ForeignKeyField class Blog(models.Model): 1 ... class Post(models.Model): n blog = ForeignKeyField(Blog) ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django >>> p.blog >>> b.post_set.all() <Blog: Blog object> [<Post: Post object>, ...]
  • 232. Related  Objects ManyToManyField class Post(models.Model): n tags = ManyToManyField(Tag) class Tag(models.Model): m ...
  • 233. Related  Objects ManyToManyField class Post(models.Model): n tags = ManyToManyField(Tag) class Tag(models.Model): m ... ¿Cómo  usamos  la  relación  desde  las  instancias? Gracias  a  nosotros Gracias  a  Django >>> p.tags.add(t1, t2) >>> t.post_set.add(p1, p2) >>> p.tags.all() >>> t.post_set.all() [<Tag: Tag object>, ...] [<Post: Post object>, ...]
  • 235. Related  Objects En  todas  ellas  podemos  renombrar  el  puntero  inverso class Blog(models.Model): 1 ... class Post(models.Model): n blog = ForeignKeyField(Blog, related_name='posts')
  • 236. Related  Objects En  todas  ellas  podemos  renombrar  el  puntero  inverso class Blog(models.Model): 1 ... class Post(models.Model): n blog = ForeignKeyField(Blog, related_name='posts') Gracias  a  nosotros Gracias  a  Django >>> p.blog >>> b.posts.all() <Blog: Blog object> [<Post: Post object>, ...]
  • 237. Related  Objects En  todas  ellas  podemos  renombrar  el  puntero  inverso class Blog(models.Model): 1 ... class Post(models.Model): n blog = ForeignKeyField(Blog, related_name='posts') Gracias  a  nosotros Gracias  a  Django >>> p.blog >>> b.posts.all() <Blog: Blog object> [<Post: Post object>, ...] Cuando  haya  2  relaciones  entre  2  modelos,  será  obligatorio
  • 238. Y  la  guinda  final:  ¡Todo  es  LAZY!
  • 240. Laziness • Las  consultas  sólo  se  ejecutarán  cuando  realmente  se   necesite  obtener  los  objetos.  En  las  siguientes  situaciones: • Iteraciones for p in Publisher.objects.all(): • Slicing Publisher.objects.filter(country='USA')[0] • Serialización [Caché] • repr() [<Publisher: Publisher object>] • len() !!! len(Publisher.objects.all()) • list() list(Publisher.objects.all()) • bool() if Publisher.objects.filter(country='USA'):
  • 241. CRUD:  Create,  Retrieve,  Update  &  Delete
  • 245. Django  admin:  Instalación urls.py from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: # from django.contrib import admin 1 # admin.autodiscover() urlpatterns = patterns('', ... 2 # url(r'^admin/', include(admin.site.urls)), ... )
  • 246. Django  admin:  Instalación urls.py from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: from django.contrib import admin 1 admin.autodiscover() urlpatterns = patterns('', ... 2 url(r'^admin/', include(admin.site.urls)), ... )
  • 247. Django  admin:  Instalación seungs.py INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 1 ... )
  • 249. Actualizando  la  BD $ python manage.py syncdb Creating table django_admin_log Installing index for admin.LogEntry model Admin  lista  para  usar
  • 252. 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)
  • 253. 1,2,3  Borrar  la  BD....  1,2,3...  Borrar  la  BD
  • 255. 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:
  • 256. Fixtures •  Es  muy  aburrido  crear  juegos  de  datos  cada  vez  que  se   elimina  una  tabla  /  BD. •  No  nos  gustan  las  cosas  aburridas. •  Ficheros  (json/xml/yaml)  para  inicializar  una  Tabla. •  Pueden  crearse  una  vez  dispongamos  de  la  información: python manage.py dumpdata <appName appName appName.model ...>
  • 257. Fixtures •  Es  muy  aburrido  crear  juegos  de  datos  cada  vez  que  se   elimina  una  tabla  /  BD. •  No  nos  gustan  las  cosas  aburridas. •  Ficheros  (json/xml/yaml)  para  inicializar  una  Tabla. •  Pueden  crearse  una  vez  dispongamos  de  la  información: python manage.py dumpdata <appName appName appName.model ...> •  Se  cargan  u0lizando: python manage.py loaddata <fixture fixture ...> •  Si  se  llaman  ini<al_data  y  están  dentro  de  la  carpeta  fixtures   de  la  app,  se  cargan  al  ahcer  el  syncdb.
  • 260. Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput <input type='text'...> CheckboxInput <input type='checkbox'...>
  • 261. Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput <input type='text'...> CheckboxInput <input type='checkbox'...> Field Lógica  de  un  campo,  asociado  a  un  Widget EmailField widget, initial, error, ... IPAddressField
  • 262. Clases  involucradas Widget Componente  visual  equivalente  a  HTML TextInput <input type='text'...> CheckboxInput <input type='checkbox'...> Field Lógica  de  un  campo,  asociado  a  un  Widget EmailField widget, initial, error, ... IPAddressField Form Conjunto  de  Fields  de  un  formulario ContactForm [nombre, email, telefono, mensaje, ...]
  • 263. Fields
  • 264. Fields ■ BooleanField ■ IPAddressField ■ CharField ■ MultipleChoiceField ■ ChoiceField ■ NullBooleanField ■ TypedChoiceField ■ RegexField ■ DateField ■ SlugField ■ DateTimeField ■ TimeField ■ DecimalField ■ URLField ■ EmailField ■ ComboField ■ FileField ■ MultiValuefield ■ FilePathField ■ SplitDateTimeField ■ FloatField ■ ModelChoiceField ■ ImageField ■ ModelMultipleChoiceField ■ IntegerField
  • 265. Creación  de  un  Form • Paso  1/3:  Definición  del  formulario  en  forms.py 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)
  • 266. Creación  de  un  Form • Paso  2/3:  Maquetación  del  formulario  en  su  template <html> <body> <h1>Contact us</h1> {% if form.errors %} <p style="color: red;"> Please correct the error{{ form.errors|pluralize }} below. </p> {% endif %} <form action="" method="post"> <table> {{ form.as_table }} </table> <input type="submit" value="Submit"> </form> </body> </html>
  • 267. Creación  de  un  Form • Paso  3/3:  Programación  de  la  vista  en  views.py 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})
  • 268. Creación  de  un  Form • Paso  3/3:  Programación  de  la  vista  en  views.py from django.shortcuts import render from mysite.contact.forms import ContactForm def contact(request): if request.method == 'POST': Pa _ern 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})
  • 269. Creación  de  un  Form • Paso  3/3:  Programación  de  la  vista  en  views.py from django.shortcuts import render from mysite.contact.forms import ContactForm def contact(request): if request.method == 'POST': Pa _ern 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})
  • 270. Creación  de  un  Form • Paso  3/3:  Programación  de  la  vista  en  views.py from django.shortcuts import render from mysite.contact.forms import ContactForm def contact(request): if request.method == 'POST': Pa _ern 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})
  • 271. Validación  propia Podemos  programar  validación  extra  asociada  a  cada  Field   del  formulario  escribiendo  un  método  clean_<fieldname>: 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
  • 272. Validación  propia Podemos  programar  validación  extra  asociada  a  cada  Field   del  formulario  escribiendo  un  método  clean_<fieldname>: 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
  • 273. Maquetación  propia Podemos  personalizar  la  maquetación  tanto  como   queramos,  prescindiendo  de  las  ayudas  de  form.as_table: ... <form action="" method="post"> <div class="field"> {{ form.subject.errors }} Para  los  diseñadores: <label for="id_subject">Subject:</label> {{ form.subject }} <style type="text/css"> </div> ul.errorlist { <div class="field"> ... {{ form.email.errors }} } <label for="id_email">E-mail:</label> .errorlist li { {{ form.email }} ... </div> } ... </style> <input type="submit" value="Submit"> </form> ...
  • 274. Forms  a  par0r  de  Models:  El  COLMO  del  DRY
  • 275. Forms  a  par-r  de  Models from django.db import models class Author(models.Model): models.py name = models.CharField(max_length=100) birth_date = models.DateField(blank=True, null=True) country = models.ModelChoiceField(Country) ... from django import forms from books.models import Author forms.py class AuthorForm(forms.ModelForm): class Meta: model = Author exclude = ('country',)
  • 277. ROSA
  • 282. Views  avanzadas Generic  Views Vistas  con  funcionalidad  genérica  parametrizable   mediante  un  diccionario  de  Extra  Op-ons Las  tuplas  de  pa>erns()  pueden  tener  3  elementos 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'}), )
  • 283. Views  avanzadas from django.views.generic.simple import direct_to_template 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'}) ) Es  la  Generic  View  más  simple  y  más  u+lizada
  • 284. Template  Library Nos  permite  extender  el  sistema  de  templates   de  Django  con  Filters  y  Tags  propios
  • 285. 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 %}
  • 286. Template  Library Nos  permite  extender  el  sistema  de  templates   de  Django  con  Filters  y  Tags  propios Uso Creación {% load milibreria %} ... {{ variable|mifiltro:"param" }} ... {% mitag param1 param2 %}
  • 287. 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.
  • 288. 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() Ejemplo def cut(value, arg=' '): return value.replace(arg, '') register.filter('cut', cut)
  • 289. 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, '')
  • 290. 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 Py thon   register = template.Library() 2.4  se  hizo   @register.filter(name='cut') sexy def cut(value, arg=' '): return value.replace(arg, '')
  • 291. Custom  Tags El  método  genérico  para  crear  Tags  es  complejo. Vamos  a  ver  cómo  crear  los  2  +pos  de  Tags  más  sencillos: SimpleTags InclusionTags • Son  inline • Son  inline • Reciben  1  argumento • Reciben  n  argumentos • Devuelven  un  string • Devuelven  un  diccionario • Insertan  su  propio   fragmento  de  template
  • 292. SimpleTags Ejemplo:  Devolver  la  hora  actual  formateada. {% current_time "%Y-%m-%d %I:%M %p" %}
  • 293. 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 ''
  • 294. InclusionTags Ejemplo:  Mostar  anuncios  si  el  usuario  no  es  premium. {% show_adverts user %} milibreria.py {% for advert in adverts %} adverts.html <img src='{{ advert.image }}' /> {% endfor %}
  • 295. InclusionTags Ejemplo:  Mostar  anuncios  si  el  usuario  no  es  premium. {% show_adverts user %} @register.inclusion_tag('website/adverts.html') def show_adverts(user): adverts = [] milibreria.py if not user.profile.is_premium: adverts = Advert.objects.order_by('?').limit(5) return {'adverts': adverts} {% for advert in adverts %} adverts.html <img src='{{ advert.image }}' /> {% endfor %}
  • 296. Middleware Nos  permite  escribir  funcionalidad  reu0lizable   que  se  inserta  en  el  flujo  de  ejecución  de  Django
  • 297. 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.""" # ...
  • 298. 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', )
  • 299. Middleware 1. Sistema  de  BETA 1. Nos  aseguramos  de  controlar  todas  páginas. 2. Si  el  usuario  +ene  una  IP  o  un  User  o... 2. Si6o  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...
  • 300. Internacionalización Ofrece  integración  con  la  librería  GNU  ge>ext  de  i18n 1. Un  fichero  .pot  con+ene  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
  • 301. Internacionalización • ¿Cómo  indicar  qué  strings  deben  ser  traducidos? • Ges+ón  cómoda  de  singulares  y  plurales