El documento presenta una introducción a Python y Django. Se divide en dos secciones principales: 1) Python, que cubre conceptos básicos como tipos de datos, operadores, estructuras y sentencias; y 2) Django, que trata sobre la arquitectura de este framework web popular como URLs, vistas, templates y el modelo. El documento proporciona una guía general sobre estos temas para aprender Python y Django.
8. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
9.
10. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
11. • Legible
• Produc/vo
• Portable
• Extenso
• Integrable
• ...
y
Diver/do
Sintaxis
intuiHva
y
estricta
Entre
1/3
y
1/5
más
conciso
que
Java
o
C++
GNU/Linux,
Windows,
Mac
OS
X,
...
Standard
Library,
Third
parHes
C,
C++,
Java,
.NET,
COM,
WS,
CORBA,
...
14. El
Intérprete
$ python holamundo.py
hola mundo!
$
Modo
Batch
#!/usr/bin/env python
print "hola mundo!"
holamundo.py
15. El
Intérprete
$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "hola mundo!"
hola mundo!
Modo
Interac*vo
$ python holamundo.py
hola mundo!
$
Modo
Batch
#!/usr/bin/env python
print "hola mundo!"
holamundo.py
16. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
17. Tipos
de
datos
h@p://docs.python.org/library/stdtypes.html
object
18. Tipos
de
datos
h@p://docs.python.org/library/stdtypes.html
object
1234 3.1415int float35Llong
19. Tipos
de
datos
h@p://docs.python.org/library/stdtypes.html
object
1234 3.1415int float35Llong
True Falsebool
20. Tipos
de
datos
h@p://docs.python.org/library/stdtypes.html
object
1234 3.1415int float35Llong
True Falsebool
'spam' "guido's" """n lines"""str
21. Tipos
de
datos
h@p://docs.python.org/library/stdtypes.html
object
1234 3.1415int float35Llong
True Falsebool
'spam' "guido's" """n lines"""str
[1, [2, 'three'], 4]list
25. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
27. Operadores
numéricos
a + b a - b a * b a / b
a % b -a +a a ** b
h@p://docs.python.org/library/operator.html
28. Operadores
numéricos
a + b a - b a * b a / b
a % b -a +a a ** b
comparadores
a < b a <= b a > b
a >= b a == b a != b
h@p://docs.python.org/library/operator.html
29. Operadores
numéricos
a + b a - b a * b a / b
a % b -a +a a ** b
comparadores
a < b a <= b a > b
a >= b a == b a != b
lógicos a or b a and b not a
h@p://docs.python.org/library/operator.html
30. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
53. Módulos
En
la
lista
de
directorios
que
conHene
la
lista
sys.path:
import math ¿Dónde
los
busca
Python?
1. El
directorio
actual:
2. El
directorio
site-packages
de
nuestro
Python:
3. Los
directorios
apuntados
por
PYTHONPATH:
4. El
directorio
de
la
instalación
de
Python:
./
/usr/local/lib/python2.6/site-packages
/usr/lib/python2.6/
$ env | grep PYTHONPATH
56. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
59. >>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
Identación
4
Espac/os
para
la
identación
60. >>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
Identación
4
Espac/os
para
la
identación
PEP 8
61. •
Guido
van
Rossum
(2001)
•
Recomendaciones
de
esHlo
•
“Readability
counts”
•
“Code
is
read
much
more
ohen
than
it
is
wriien.”
•
Muy
recomendable
importante
seguirlo.
PEP 8
¿PEP
8?
h@p://www.python.org/dev/peps/pep-‐0008/
76. 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
77. 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
78. Funciones
interesantes
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> zip(a,b)
[(1, 4), (2, 5), (3, 6)]
>>> round(1.2345, 2)
1.23
>>> sorted([5,1,3,4,2])
[1, 2, 3, 4, 5]
Son
sólo
un
ejemplo...
h@p://docs.python.org/library/func/ons.html
79. Funciones
interesantes
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> zip(a,b)
[(1, 4), (2, 5), (3, 6)]
>>> round(1.2345, 2)
1.23
>>> sorted([5,1,3,4,2])
[1, 2, 3, 4, 5]
>>> map(str,[1,2,3,4,5])
['1', '2', '3', '4', '5']
Son
sólo
un
ejemplo...
h@p://docs.python.org/library/func/ons.html
82. 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)
83. class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
def hello(self):
return 'My name is %s' % self.name
Clases
s = Student("Jorge", 24)
camelCase
84. class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
def hello(self):
return 'My name is %s' % self.name
1 2
3
4
5
Clases
s = Student("Jorge", 24)
camelCase
PEP 8
85. El
operador
()
• Es
importante
diferenciar:
funcion
vs
funcion()
Clase
vs
Clase()
• El
operador
()
permite:
• Invocar
funciones:
• Instanciar
clases:
resultado = funcion()
objeto = Clase("param1")
86. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
87. $name = "Jon";
if($name == "Jon"){
$name = "Jon Rocks!";
}
elseif($name == "Mary"){
$name = "Hello Mary";
}
else{
$name = "Who are you?"
}
name = "Jon"
if name == "Jon":
name = "Jon Rocks!"
elif name == "Mary":
name = "Hello Mary"
else:
name = "Who are you?"
Sentencias:
if-‐else
88. $count = 0;
while ($count < 5) {
echo "Number ".$count;
$count+=1;
}
count = 0
while count < 5:
print "Number %i" % count
count+=1
Sentencias:
while
89. for ($i=0; $i < 5; $i++) {
echo "Number ".$count;
}
for i in range(4):
print "Number %i" % count
Sentencias:
for
92. •
Python
es
un
lenguaje
fácil
de
aprender.
•
Menos
código:
•
Muchos
Muchísimos
menos
errores
de
Sintaxis.
•
Mayor
velocidad
de
escritura.
•
ProtoHpado...
UHlizado
por
grandes
empresas.
Conclusiones
93. •
Python
es
un
lenguaje
fácil
de
aprender.
•
Menos
código:
•
Muchos
Muchísimos
menos
errores
de
Sintaxis.
•
Mayor
velocidad
de
escritura.
•
ProtoHpado...
UHlizado
por
grandes
empresas.
etc...
Conclusiones
98. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
99. Evolución
de
la
Web
Desarrollo
Web
1ª
Generación 2ª
Generación 3ª
Generación
HTML
CGI
PHP
ASP
JSP
...
Django
Rails
Symfony
...
102. •
Loose
coupling,
Acoplamiento
débil.
•
Cada
capa
es
independiente
y
desconoce
completamente
a
las
demás.
•
Menos
código.
•
Rápido
desarrollo.
•
Esto
es
el
siglo
21,
todo
el
trabajo
tedioso
hay
que
evitarlo.
•
Don’t
Repeat
Yourself
(DRY)
Filoso]a
103. •
Loose
coupling,
Acoplamiento
débil.
•
Cada
capa
es
independiente
y
desconoce
completamente
a
las
demás.
•
Menos
código.
•
Rápido
desarrollo.
•
Esto
es
el
siglo
21,
todo
el
trabajo
tedioso
hay
que
evitarlo.
•
Don’t
Repeat
Yourself
(DRY)
Every distinct concept and/or piece of data should live in
one, and only one, place. Redundancy is bad.
Normalization is good.”
“
Filoso]a
104. •
Explicit
is
beier
than
implicit.
•
Este
es
un
principio
de
Python.
•
Django
no
debe
hacer
demasiada
“Magia”.
•
Si
algo
es
“Mágico”
ha
de
haber
una
buena
razón.
•
Consistencia
•
Ha
de
ser
consistente
a
todos
los
niveles.
•
Eficiencia,
Seguridad,
Flexibilidad
y
Simplicidad.
Filoso]a
h@p://docs.djangoproject.com/en/dev/misc/design-‐philosophies/
110. Configurar
un
motor
de
Base
de
Datos:
•
Oficiales:
•
PostgreSQL
•
MySQL
•
Oracle
•
SQLite
•
Comunidad:
•
Sybase
SQL
Anywhere
•
IBM
DB2
•
Microsoh
SQL
Server
2005
•
Firebird
•
ODBC
2.
Instalación
SGBD
111. Configurar
un
motor
de
Base
de
Datos:
•
Oficiales:
•
PostgreSQL
•
MySQL
•
Oracle
•
SQLite
•
Comunidad:
•
Sybase
SQL
Anywhere
•
IBM
DB2
•
Microsoh
SQL
Server
2005
•
Firebird
•
ODBC
2.
Instalación
SGBD
112. •
Vamos
a
uHlizar
SQLite
por
comodidad
•
Desde
Python
2.5
podemos
uHlizar
sqlite
sin
instalar
nada.
2.
Instalación
SGBD
113. •
Vamos
a
uHlizar
SQLite
por
comodidad
•
Desde
Python
2.5
podemos
uHlizar
sqlite
sin
instalar
nada.
2.
Instalación
SGBD
119. *
Incluida
la
carpeta
del
proyecto
Ficheros
y
Carpetas¿Es
Django
tán
simple
y
fácil
de
usar?
120. *
Incluida
la
carpeta
del
proyecto
Ficheros
y
Carpetas
Ficheros
Carpetas
¿Es
Django
tán
simple
y
fácil
de
usar?
121. Rails Symfony
149 117
35 29
*
Incluida
la
carpeta
del
proyecto
Ficheros
y
Carpetas
Ficheros
Carpetas
¿Es
Django
tán
simple
y
fácil
de
usar?
122. Rails Symfony
149 117
35 29
*
Incluida
la
carpeta
del
proyecto
Ficheros
y
Carpetas
Ficheros
Carpetas
¿Es
Django
tán
simple
y
fácil
de
usar?
123. Rails Symfony
149 117
35 29
*
Incluida
la
carpeta
del
proyecto
Ficheros
y
Carpetas
Django
5
2
Ficheros
Carpetas
¿Es
Django
tán
simple
y
fácil
de
usar?
127. Crear
nuestro
proyecto
$ django-admin.py startproject dwitter
-‐
¿Esto
es
un
proyecto...
?
Si
os
ve
mi
jefe...
.
!"" dwitter
# !"" __init__.py
# !"" settings.py
# !"" urls.py
# $"" wsgi.py
$"" manage.py
-‐
Sí,
disponemos
de
un
proyecto
‘funcional’
en
django.
de
5
ficheros
;-‐)
130. Arrancar
nuestro
proyectode
5
ficheros
;-‐)
$ cd dwitter
$ python manage.py runserver
Validating models...
0 errors found
Django version 1.4, using settings 'dwitter.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
131. Arrancar
nuestro
proyectode
5
ficheros
;-‐)
$ cd dwitter
$ python manage.py runserver
Validating models...
0 errors found
Django version 1.4, using settings 'dwitter.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
132. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
134. URLs
y
Vistas
• El
fichero
urls.py
actúa
como
puerta
de
entrada
para
las
pe*ciones
HTTP
• Se
definen
URLs
elegantes
mediante
expresiones
regulares
que
redirigen
a
funciones
de
views.py
urls.py
views.py
hGp://mysite.com/about/
html ...
¿urlpaGerns?
135. URLs
y
Vistas
• La
función
de
views.py
recibe
como
parámetros
un
objeto
H@pRequest
y
todos
los
parámetros
de
la
URL
capturados,
teniendo
que
devolver
siempre
un
objeto
H@pResponse
views.py
H@pRequest(),
...
H@pResponse()
136. URLs
y
Vistas
Ejemplo
1:
http://mysite.com/time
from django.conf.urls.defaults import *
from mysite.views import hora_actual
urlpatterns = patterns('',
url(r'^time/$', hora_actual),
)
from django.http import HttpResponse
from datetime import datetime
def hora_actual(request):
now = datetime.now()
html = "Son las %s." % now
return HttpResponse(html)
urls.py
views.py
137. URLs
y
Vistas
from django.conf.urls.defaults import *
from mysite.views import dentro_de
urlpatterns = patterns('',
url(r'^time/plus/(d{1,2})/$', dentro_de),
)
from django.http import HttpResponse
from datetime import datetime, timedelta
def dentro_de(request, offset):
offset = int(offset)
dt = datetime.now() + timedelta(hours=offset)
html = "En %i hora(s), serán las %s." % (offset, dt)
return HttpResponse(html)
urls.py
views.py
Ejemplo
2:
http://mysite.com/time/plus/2
138.
139. URLs
y
Vistas
from django.conf.urls.defaults import *
from mysite.views import dentro_de
urlpatterns = patterns('',
url(r'^time/plus/(d{1,2})/$', dentro_de),
)
from django.http import HttpResponse
from datetime import datetime, timedelta
def dentro_de(request, offset):
offset = int(offset)
dt = datetime.now() + timedelta(hours=offset)
html = "En %i hora(s), serán las %s." % (offset, dt)
return HttpResponse(html)
urls.py
views.py
Ejemplo
2:
http://mysite.com/time/plus/2
141. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
142. Templates
• Separan
la
lógica
de
presentación
a
una
capa
independiente.
• Ficheros
independientes
(.html)
• Lenguaje
independiente
(¡para
diseñadores!)
143. Templates
• Se
basan
en
dos
*pos
de
objetos:
Template()
y
Context().
• Un
objeto
Template()
con*ene
el
string
de
salida
que
queremos
devolver
en
el
HGpResponse
(normalmente
HTML),
pero
incluyendo
e*quetas
especiales
de
Django.
• Un
objeto
Context()
con*ene
un
diccionario
con
los
valores
que
dan
contexto
a
una
plan*lla,
los
que
deben
usarse
para
renderizar
un
objeto
Template().
"Bienvenido, {{ user }}."
{'user': 'alatar'}
Template:
Context:
"Bienvenido, alatar."
144. Templates
from django.http import HttpResponse
from django.template import Template, Context
from datetime import datetime
PLANTILLA = """<html><body>
Son las {{ hora }}.
</body></html>"""
def hora_actual(request):
now = datetime.now()
t = Template(PLANTILLA)
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
• Primera
aproximación
al
obje*vo:
Template
+
Context
145. Templates
• Segunda
aproximación
al
obje*vo:
open(),
read(),
close()
from django.http import HttpResponse
from django.template import Template, Context
from datetime import datetime
def hora_actual(request):
now = datetime.now()
fp = open('/home/django/templates/hora.html')
t = Template(fp.read())
fp.close()
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
146. Templates
• Segunda
aproximación
al
obje*vo:
open(),
read(),
close()
from django.http import HttpResponse
from django.template import Template, Context
from datetime import datetime
def hora_actual(request):
now = datetime.now()
fp = open('/home/django/templates/hora.html')
t = Template(fp.read())
fp.close()
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
147. Templates
• Segunda
aproximación
al
obje*vo:
open(),
read(),
close()
from django.http import HttpResponse
from django.template import Template, Context
from datetime import datetime
def hora_actual(request):
now = datetime.now()
fp = open('/home/django/templates/hora.html')
t = Template(fp.read())
fp.close()
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
Boring
boilerplate
code!
148. Templates
• Tercera
aproximación
al
obje*vo:
get_template()
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from datetime import datetime
def hora_actual(request):
now = datetime.now()
t = get_template('hora.html')
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
TEMPLATE_DIRS = (
'/home/django/templates',
)
senngs.py
149. Templates
• Tercera
aproximación
al
obje*vo:
get_template()
TEMPLATE_DIRS = (
'/home/django/templates',
)
senngs.py
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from datetime import datetime
def hora_actual(request):
now = datetime.now()
t = get_template('hora.html')
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
150. Templates
• Tercera
aproximación
al
obje*vo:
get_template()
TEMPLATE_DIRS = (
'/home/django/templates',
)
senngs.py
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from datetime import datetime
def hora_actual(request):
now = datetime.now()
t = get_template('hora.html')
c = Context({'hora': now})
html = t.render(c)
return HttpResponse(html)
S*ll
boring...
151. Templates
• Obje*vo
alcanzado:
render()
from django.shortcuts import render
from datetime import datetime
def hora_actual(request):
now = datetime.now()
return render(request, 'hora.html', {'hora': now})
152. Templates
• Obje*vo
alcanzado:
render()
from django.shortcuts import render
from datetime import datetime
def hora_actual(request):
now = datetime.now()
return render(request, 'hora.html', {'hora': now})
Boring...?
153. Templates
• Obje*vo
alcanzado:
render()
from django.shortcuts import render
from datetime import datetime
def hora_actual(request):
now = datetime.now()
return render(request, 'hora.html', {'hora': now})
AWESOME!
156. Templates:
Tip
TEMPLATE_DIRS = (
'/home/django/templates',
)
senngs.py Reusable
apps?
a)
b)
• La
carpeta
/templates
es
buscada
dentro
de
cada
app.
• Conviene
incluir
una
carpeta
con
el
nombre
de
la
app
por
claridad.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
return render(request, 'website/index.html')
Alterna*va
reu*lizable:
157. ¡Empieza
nuestro
primer
proyecto!
a) Crear
la
app
dwiier.website.
b)Incluir
la
app
en
sesngs.py.
c) Definir
una
vista
para
la
URL
“/”
que
devuelva
el
texto:
“Welcome
to
dwiier!”:
‣ /
‣ timeline(request)
165. Tarea:
URLs
y
Vistas
a) Implementar
la
vista
timeline()
para
que
renderice
un
Hmeline
de
twiier
en
una
template
index.html
a
parHr
de
datos
hardcodeados
en
un
diccionario.
h@p://bit.ly/diccionario-‐tweets
166. 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
167. Filoso]a
y
Limitaciones
•
La
sintaxis
debe
estar
desacoplada
del
HTML/XML.
•
Los
diseñadores
saben
HTML.
•
Los
diseñadores
no
saben
Python.
•
No
consiste
en
inventarse
un
lenguaje.
•
Una
variable
no
puede
cambiar
el
valor
de
una
variable.
•
Una
template
no
puede
ejecutar
código
Python.
179. Templates:
tags
{%
%}
cycle {% for elemento in lista %}
<li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
{% endfor %}
180. Templates:
tags
{%
%}
cycle {% for elemento in lista %}
<li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
{% endfor %}
include {% include "foo/bar.html" %}
181. Templates:
tags
{%
%}
cycle {% for elemento in lista %}
<li class="{% cycle 'rojo' 'azul' %}">{{ elemento }}<li>
{% endfor %}
include {% include "foo/bar.html" %}
forloop {% for elemento in lista %}
<li>{{ forloop.counter }}.{{ elemento }}<li>
{% endfor %}
182. 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 %}
183.
Tarea:
Tags
a) UHlizar
tags
para
que
el
Hmeline
se
muestre
con
el
siguiente
formato:
• <username>:
<tweet>
<Hmestamp>
• <username>:
<tweet>
<Hmestamp>
• ...
184.
Tarea:
Tags
avanzados
a) Hacer
que
el
Hmeline
muestre
el
mensaje
“No
hay
tweets.”
si
el
diccionario
recibido
está
vacío.
195. Templates:
Filters
{'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'}
{{ username|striptags }}striptags
Juan es majo guapo y listo
{{ username|truncatewords_html:4 }}truncatewords_html
Juan es <b>majo guapo</b> ...
196. Templates:
Filters
{'username': 'Juan es <b>majo, guapo y <em>listo</em></b>'}
{{ username|striptags }}striptags
Juan es majo guapo y listo
{{ username|truncatewords_html:4 }}truncatewords_html
Juan es <b>majo guapo</b> ...
{{ username|removetags:”em a br” }}removetags
Juan es <b>majo guapo y listo</b>
208. Tarea:
Filters
a) Añadir
a
cada
tweet
del
Hmeline
el
Hempo
transcurrido:
• <username>:
<tweet>
<n>
seconds
ago
• <username>:
<tweet>
<n>
minutes
ago
• ...
209. Tarea:
Filters
b)Formatear
las
publicaciones
de
HOYGANs
convirHendo
el
texto
a
minúsculas
capitalizadas:
‣“HOYGAN
NESESITO
QUE
MAYUDEN
A
HASER
UN
PROGRAMA
EN
DJANGO
GRASIAS
DE
ANTEBRASO”
‣“Hoygan
necesito
que
mayuden
a
haser
un
programa
en
django
grasias
de
antebraso”
210. Tarea:
Filters
c) Conseguir
que
todas
las
urls
que
aparezcan
en
los
tweets
se
conviertan
en
enlaces
<a
href=...
/>
de
HTML.
211. 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 %}
212. Tarea:
Herencia
de
templates
a) Descargar
nuestra
template
base.html.
b)Incluirla
en
vuestra
app.
c) Hacer
que
vuestro
index.html
herede
de
base.html
y
exHenda
el
bloque
‘content’
con
su
contenido.
h@p://bit.ly/base-‐html-‐template
213. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
224. Modelo
from django.db import models
class Books(models.Model):
name = models.CharField(blank=True, max_length=100)
created = models.DateTimeField(blank=False)
available = models.BooleanField(default=True)
•
Independencia
SGBD!
•
Definimos
estructuras
de
información
genéricas.
•
Definimos
restricciones
(notnull,
blank,
max_lenght...)
•
Única
definición
del
modelo
(configuración,
mapeo
a
db)
225. Modelo
from django.db import models
class Books(models.Model):
name = models.CharField(blank=True, max_length=100)
created = models.DateTimeField(blank=False)
available = models.BooleanField(default=True)
2
1
3
4
5
6
•
Independencia
SGBD!
•
Definimos
estructuras
de
información
genéricas.
•
Definimos
restricciones
(notnull,
blank,
max_lenght...)
•
Única
definición
del
modelo
(configuración,
mapeo
a
db)
231. ¿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;
232. ¿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;
233. ¿Es
magia?
No.
•
Nombres
de
tablas
generados
automáHcamente.
•
<app_name>_lower(<model_name>)
•
id
como
Primary
Key
(Personalizable)
•
Las
Foreing
Key
terminan
en
_id
(Personalizable)
•
Los
Hpos
de
datos
se
ajustan
en
función
del
SGBD
236. Creando
Tablas
•
Crea
las
tablas
para
todos
los
modelos
de
las
apps
instaladas
en
el
fichero
sesngs.py
•
No
actualiza
esquemas
si
la
tabla
existe.
•
Eliminar
tabla
y
volver
a
ejecutar
syncdb
237. Creando
Tablas
$ python manage.py syncdb
•
Crea
las
tablas
para
todos
los
modelos
de
las
apps
instaladas
en
el
fichero
sesngs.py
•
No
actualiza
esquemas
si
la
tabla
existe.
•
Eliminar
tabla
y
volver
a
ejecutar
syncdb
239. syncdb
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table website_tweet
You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
240. syncdb
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table website_tweet
You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
django.contrib.auth
244. syncdb
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table website_tweet
You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
website.tweet
245. syncdb
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table website_tweet
You just installed Django's auth system, which means you don't have any
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin
E-mail address: user@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
django.contrib.auth
261. SELECT
de
1
resultado
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
.get(...)
262. SELECT
de
1
resultado
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
.get(...)
>>> Publisher.objects.get(name="Anaya")
Traceback (most recent call last):
...
DoesNotExist: Publisher matching query does not exist.
263. SELECT
de
1
resultado
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
.get(...)
>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
...
MultipleObjectsReturned: get() returned more than one Publisher --
it returned 2! Lookup parameters were {'country': 'U.S.A.'}
>>> Publisher.objects.get(name="Anaya")
Traceback (most recent call last):
...
DoesNotExist: Publisher matching query does not exist.
284. Related
Objects
OneToOneField
class Coche(models.Model):
motor = OneToOneField(Motor)
class Motor(models.Model):
...
>>> c.motor
<Motor: Motor object>
>>> m.coche
<Coche: Coche object>
¿Cómo
usamos
la
relación
desde
las
instancias?
Gracias
a
nosotros Gracias
a
Django
1
1
287. Related
Objects
ForeignKeyField
class Blog(models.Model):
...
class Post(models.Model):
blog = ForeignKeyField(Blog)
>>> p.blog
<Blog: Blog object>
>>> b.post_set.all()
[<Post: Post object>, ...]
¿Cómo
usamos
la
relación
desde
las
instancias?
Gracias
a
nosotros Gracias
a
Django
1
n
290. Related
Objects
ManyToManyField
class Post(models.Model):
tags = ManyToManyField(Tag)
class Tag(models.Model):
...
>>> p.tags.add(t1, t2)
>>> p.tags.all()
[<Tag: Tag object>, ...]
>>> t.post_set.add(p1, p2)
>>> t.post_set.all()
[<Post: Post object>, ...]
¿Cómo
usamos
la
relación
desde
las
instancias?
Gracias
a
nosotros Gracias
a
Django
n
m
292. Related
Objects
En
todas
ellas
podemos
renombrar
el
puntero
inverso
class Blog(models.Model):
...
class Post(models.Model):
blog = ForeignKeyField(Blog, related_name='posts')
1
n
293. Related
Objects
En
todas
ellas
podemos
renombrar
el
puntero
inverso
class Blog(models.Model):
...
class Post(models.Model):
blog = ForeignKeyField(Blog, related_name='posts')
>>> p.blog
<Blog: Blog object>
>>> b.posts.all()
[<Post: Post object>, ...]
Gracias
a
nosotros Gracias
a
Django
1
n
294. Related
Objects
En
todas
ellas
podemos
renombrar
el
puntero
inverso
class Blog(models.Model):
...
class Post(models.Model):
blog = ForeignKeyField(Blog, related_name='posts')
>>> p.blog
<Blog: Blog object>
>>> b.posts.all()
[<Post: Post object>, ...]
Gracias
a
nosotros Gracias
a
Django
1
n
Cuando
haya
2
relaciones
entre
2
modelos,
será
obligatorio
297. Laziness
• Las
consultas
sólo
se
ejecutarán
cuando
realmente
se
necesite
obtener
los
objetos.
En
las
siguientes
situaciones:
• Iteraciones
• Slicing
• Serialización
• repr()
• len() !!!
• list()
• bool()
for p in Publisher.objects.all():
Publisher.objects.filter(country='USA')[0]
[Caché]
[<Publisher: Publisher object>]
len(Publisher.objects.all())
list(Publisher.objects.all())
if Publisher.objects.filter(country='USA'):
304. Usando
el
ORM
a)Insertar
varios
Tweets
desde
la
shell.
b)Modificar
views.timeline
para
que
uHlice
los
Tweets
reales
de
la
BD.
305. Usando
el
ORM
c) Implementar
la
vista
tweet_page()
como
permalink
de
un
tweet:
‣ URL:
tweet/<tweet_id>/
‣ View:
tweet_page
‣ Template:
tweet_page.html
(Descargar)
d)Lanzar
Http404
si
no
existe
el
tweet_id.
e)shortcut!:
get_object_or_404()
h@p://bit.ly/tweet-‐page
307. Profile
•
Problema:
El
modelo
User
de
django.contrib.auth
no
puede
contener
toda
la
información
que
necesitamos.
•
Username,
Password,
Name....
y
poco
más.
•
Solución:
Definir
un
Profile
(Un
Modelo
Agregado)
para
guardar
esa
información.
309. Profile
class Profile(models.Model):
user = models.OneToOneField(User, unique=True)
bio = models.CharField(blank=True, max_length=200)
...
models.py
•
Cada
objeto
User
de
django.contrib.auth
dispondrá
de
un
atributo
profile
que
nos
permiHrá
acceder
al
Profile.
311. Profile
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(id=1)
>>> type(u)
<class 'django.contrib.auth.models.User'>
>>> type(u.profile)
<class 'website.models.Profile'>
•Donde
tengamos
el
User
tendremos
el
Profile.
•Donde
tengamos
el
Profile,
tendremos
el
User.
313. Signals
•
Django
incorpora
un
dispacher
de
señales
para
ayudar
a
crear
aplicaciones
reuHlizables.
•
Permite
subscribirnos
a
“eventos”
a
lo
largo
de
todo
el
framework
y
actuar
frente
a
ellos
(¡Observer-‐Observable!).
•
Señales
interesantes:
• pre_save, post_save
• pre_delete, post_delete
• m2m_changed
• request_started, request_finished
h@p://docs.djangoproject.com/en/dev/ref/signals/
315. Signals
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
from django.db.models.signals import post_save
post_save.connect(create_user_profile, sender=User)
1
2
3
Puede
estar
en
cualquier
app
de
nuestro
proyecto.
Se
recomienda
models.py
316. Users
en
dwiier
a)Crear
el
modelo
Profile
b)Crear
signal
para
agregar
un
objeto
Profile
a
cada
objeto
User
creado.
c) Eliminar
BD.
d)Hacer
syncdb
319. Profile
class Profile(models.Model):
user = models.OneToOneField(User, unique=True)
bio = models.CharField(blank=True, max_length=200)
followers = models.ManyToManyField("self", blank=True,
symmetrical=False,
related_name="following")
models.py
•
m2m
symmetrical
(por
defecto)
•
Si
yo
te
sigo
a
H,
tú
me
sigues
a
mi.
•
related_name
(en
este
caso)
•
Limpieza
y
evitar
profile_set
322. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
327. Django
admin:
Instalación
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
urlpatterns = patterns('',
...
# url(r'^admin/', include(admin.site.urls)),
...
)
1
2
urls.py
328. Django
admin:
Instalación
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
...
url(r'^admin/', include(admin.site.urls)),
...
)
1
2
urls.py
335. 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)
339. Fixtures
•
Es
muy
aburrido
crear
juegos
de
datos
cada
vez
que
se
elimina
una
tabla
/
BD.
•
No
nos
gustan
las
cosas
aburridas.
•
Ficheros
(json/xml/yaml)
para
inicializar
una
Tabla.
•
Pueden
crearse
una
vez
dispongamos
de
la
información:
340. Fixtures
•
Es
muy
aburrido
crear
juegos
de
datos
cada
vez
que
se
elimina
una
tabla
/
BD.
•
No
nos
gustan
las
cosas
aburridas.
•
Ficheros
(json/xml/yaml)
para
inicializar
una
Tabla.
•
Pueden
crearse
una
vez
dispongamos
de
la
información:
python manage.py dumpdata <appName appName appName.model ...>
341. Fixtures
•
Es
muy
aburrido
crear
juegos
de
datos
cada
vez
que
se
elimina
una
tabla
/
BD.
•
No
nos
gustan
las
cosas
aburridas.
•
Ficheros
(json/xml/yaml)
para
inicializar
una
Tabla.
•
Pueden
crearse
una
vez
dispongamos
de
la
información:
python manage.py dumpdata <appName appName appName.model ...>
•
Se
cargan
uHlizando:
python manage.py loaddata <fixture fixture ...>
•
Si
se
llaman
iniAal_data
y
están
dentro
de
la
carpeta
fixtures
de
la
app,
se
cargan
al
ahcer
el
syncdb.
342. Tarea:
Avance
en
dwiier
a)Implementar
la
vista
user_page()
para
ofrecer
un
perfil
de
usuario
con
su
Hmeline
personal:
‣ URL:
user/<username>/
‣ View:
user_page
‣ Template:
user_page.html
h@p://bit.ly/user-‐page
343. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
347. Clases
involucradas
Widget Componente
visual
equivalente
a
HTML
TextInput
CheckboxInput
<input type='text'...>
<input type='checkbox'...>
Field Lógica
de
un
campo,
asociado
a
un
Widget
EmailField
IPAddressField
widget, initial, error, ...
348. Clases
involucradas
Widget Componente
visual
equivalente
a
HTML
TextInput
CheckboxInput
<input type='text'...>
<input type='checkbox'...>
Field Lógica
de
un
campo,
asociado
a
un
Widget
EmailField
IPAddressField
widget, initial, error, ...
Form Conjunto
de
Fields
de
un
formulario
ContactForm [nombre, email, telefono, mensaje, ...]
352. Creación
de
un
Form
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100, label='Topic')
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
• Paso
1/3:
Definición
del
formulario
en
forms.py
353. Creación
de
un
Form
<html>
<body>
<h1>Contact us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
</body>
</html>
• Paso
2/3:
Maquetación
del
formulario
en
su
template
354. Creación
de
un
Form
from django.shortcuts import render
from mysite.contact.forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(cd['subject'], cd['message'], ...)
# ...
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
• Paso
3/3:
Programación
de
la
vista
en
views.py
355. Creación
de
un
Form
from django.shortcuts import render
from mysite.contact.forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(cd['subject'], cd['message'], ...)
# ...
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
• Paso
3/3:
Programación
de
la
vista
en
views.py
Paiern
356. Creación
de
un
Form
from django.shortcuts import render
from mysite.contact.forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(cd['subject'], cd['message'], ...)
# ...
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
• Paso
3/3:
Programación
de
la
vista
en
views.py
Paiern
357. Creación
de
un
Form
from django.shortcuts import render
from mysite.contact.forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(cd['subject'], cd['message'], ...)
# ...
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
• Paso
3/3:
Programación
de
la
vista
en
views.py
Paiern
358. Validación
propia
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
num_words = len(message.split())
if num_words < 4:
raise forms.ValidationError("Not enough words!")
return message
Podemos
programar
validación
extra
asociada
a
cada
Field
del
formulario
escribiendo
un
método
clean_<fieldname>:
359. Validación
propia
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
num_words = len(message.split())
if num_words < 4:
raise forms.ValidationError("Not enough words!")
return message
Podemos
programar
validación
extra
asociada
a
cada
Field
del
formulario
escribiendo
un
método
clean_<fieldname>:
360. Maquetación
propia
...
<form action="" method="post">
<div class="field">
{{ form.subject.errors }}
<label for="id_subject">Subject:</label>
{{ form.subject }}
</div>
<div class="field">
{{ form.email.errors }}
<label for="id_email">E-mail:</label>
{{ form.email }}
</div>
...
<input type="submit" value="Submit">
</form>
...
Podemos
personalizar
la
maquetación
tanto
como
queramos,
prescindiendo
de
las
ayudas
de
form.as_table:
<style type="text/css">
ul.errorlist {
...
}
.errorlist li {
...
}
</style>
Para
los
diseñadores:
362. Forms
a
par/r
de
Models
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
birth_date = models.DateField(blank=True, null=True)
country = models.ModelChoiceField(Country)
...
from django import forms
from books.models import Author
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
exclude = ('country',)
models.py
forms.py
363. Primer
Form
en
dwiier
a)Crear
un
Form
que
permita
publicar
tweets
desde
Hmeline.html
al
usuario
que
esté
logueado
desde
django.contrib.admin
(no
tenemos
login
propio
de
momento).
364. Tarea:
Avance
en
dwiier
a)Implementar
la
vista
users_list()
para
visualizar
la
lista
de
usuarios:
‣ URL:
users/
‣ View:
users_list
‣ Template:
users_list.html
(Descargar)
h@p://bit.ly/users-‐list
365. Índice
1.Python
a. Introducción
b.Tipos
de
datos
c. Operadores
d.Usos
frecuentes
e. Estructuras
f. Sentencias
g. Ejercicio
2.Django
a. Introducción
b.URLs
y
Vistas
c. Templates
d.Modelo
e. Administración
f. Formularios
g. Magia
avanzada
Proyecto
369. Views
avanzadas
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^hello/$', 'mysite.views.hello'),
url(r'^time/$', 'mysite.views.current_datetime'),
url(r'^time/plus/(d{1,2})/$', 'mysite.views.hours_ahead'),
)
El
primer
parámetro
de
pa@erns()
sirve
de
algo
370. Views
avanzadas
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^hello/$', 'mysite.views.hello'),
url(r'^time/$', 'mysite.views.current_datetime'),
url(r'^time/plus/(d{1,2})/$', 'mysite.views.hours_ahead'),
)
from django.conf.urls.defaults import *
urlpatterns = patterns('mysite.views',
url(r'^hello/$', 'hello'),
url(r'^time/$', 'current_datetime'),
url(r'^time/plus/(d{1,2})/$', 'hours_ahead'),
)
¡El
primer
parámetro
de
pa@erns()
sirve
de
algo!
371. Views
avanzadas
En
ficheros
urls.py
que
gesHonen
varias
apps...
from django.conf.urls.defaults import *
urlpatterns = patterns('mysite.views',
url(r'^hello/$', 'hello'),
url(r'^time/$', 'current_datetime'),
url(r'^time/plus/(d{1,2})/$', 'hours_ahead'),
)
urlpatterns += patterns('weblog.views',
url(r'^tag/(w+)/$', 'tag'),
)
372. Views
avanzadas
En
ficheros
urls.py
que
gesHonen
varias
apps...
from django.conf.urls.defaults import *
urlpatterns = patterns('mysite.views',
url(r'^hello/$', 'hello'),
url(r'^time/$', 'current_datetime'),
url(r'^time/plus/(d{1,2})/$', 'hours_ahead'),
)
urlpatterns += patterns('weblog.views',
url(r'^tag/(w+)/$', 'tag'),
)
381. Views
avanzadas
Generic
Views
Vistas
con
funcionalidad
genérica
parametrizable
mediante
un
diccionario
de
Extra
Op/ons
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
url(r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}),
url(r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),
)
Las
tuplas
de
pa@erns()
pueden
tener
3
elementos
382. Views
avanzadas
Renderiza
directamente
la
template
indicada
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
url(r'^about/$', direct_to_template, {'template': 'about.html'})
)
from django.views.generic.simple import direct_to_template
Es
la
Generic
View
más
simple
y
más
uHlizada
383. Extra
OpHons
en
urls.py
a)Definir
dos
nuevas
URLs
en
urls.py
que
se
sirvan
de
las
vistas
de
django.contrib.auth
para
implementar
login
y
logout:
‣ URL:
login/
‣ View:
auth.views.login
‣ Template:
login.html
(Descargar)
‣ URL:
logout/
‣ View:
auth.views.logout
‣ Template:
[redirect a /]
h@p://bit.ly/login-‐template
386. Context
Processors
¿Context
Processors?
Son
funciones.
• Reciben
un
HGpRequest()
como
único
parámetro.
• Devuelven
un
diccionario
para
ser
usado
como
Context().
387. Context
Processors
¿Context
Processors?
Son
funciones.
def ip_address_processor(request):
return {'ip_address': request.META['REMOTE_ADDR']}
• Reciben
un
HGpRequest()
como
único
parámetro.
• Devuelven
un
diccionario
para
ser
usado
como
Context().
388. Context
Processors
¿Context
Processors?
Son
funciones.
def ip_address_processor(request):
return {'ip_address': request.META['REMOTE_ADDR']}
• Reciben
un
HGpRequest()
como
único
parámetro.
• Devuelven
un
diccionario
para
ser
usado
como
Context().
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.contrib.messages.context_processors.messages",
"website.context_processors.ip_address_processor",
)
389. Context
Processors
En
lugar
de
encapsular
sólo
el
contexto
de
esta
vista
con
Context,
la
función
render()
instancia
RequestContext,
que
alimenta
nuestro
diccionario
con
todos
los
diccionarios
devueltos
por
los
Context
Processors
que
tengamos
habilitados.
def view(request):
...
return render(request, '...html', {'...': ...})
def render(request, template, context):
t = get_template(template)
c = RequestContext(request, context)
html = t.render(c)
return HttpResponse(html)
390. ContextProcessors
en
dwiier
c) Cuando
el
usuario
esté
logueado,
mostrar
Bienvenido,
<username>
y
un
link
para
desloguearse.
d)Cuando
no
esté
logueado,
mostrar
un
link
a
/login.
e)Tip:
user.is_authenHcated()
393. 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 %}