You are on page 1of 25

TUTORIAL DJANGO

Escribiendo mi primera aplicacin con Django


Vamos a aprender con el ejemplo.
A lo largo de este tutorial, le guiaremos a travs de la creacin de una aplicacin bsica de la encuesta.
Se va a constar de dos partes:

Un sitio pblico que permite a la gente ver las encuestas y votar en ellas.
Un sitio de administracin que le permite agregar, modificar y eliminar las encuestas.
Bueno empezaremos por la instalacin en mi caso instalaremos Django en Mac:
Python ya viene instalado en mac al igual que en Linux, en Windows si les toca instalar Python.
Comandos en consola
$python
Exit
$sudo easy_install pip
$sudo pip install virtual env
$ls
$pwd
$cd carpeta/
$cd ../
$virtualenv entorno
$source bin/activate
(entorno)$pip freeze
(entorno)$pip install django==1.45
(entorno)$pip install django upgrade
Realiza
Muestra la versin de python, y entra al Shell
Sale del Shell de python
Instala pip
Instala virtualenv
Para ver los archivos contenidos
Ve la direccin en donde te encuentras
Accede a carpeta
Sale de carpeta
Crea un entorno virtual
Entras a la carpeta y activas el entorno virtual
Ves lo que tienes instalado
Instalas django 1.45
Actualizas django a la versin mas reciente

Creacin de un proyecto
Creamos el proyecto con la linea

$ django-admin.py startproject miproyecto


Configuracin de base de datos
Ahora, editar

miproyecto/settings.py. bueno para comenzar solo comenzaremos la ubicacin de nuestra regin y si deseamos la

en nombre y tipo de base de datos a usar, para mi zona horaria pondr:

LANGUAGE_CODE = es-pe
Posterioemente y obedeciendo a django 1.7 tenemos que migrar la bd.

$ Python manage.py migrate


El servidor de desarrollo
Vamos a echarle un vistazo a nuestro servidor de desarrollo con:

$ python manage.py runserver


Con esto accedemos a http://127.0.0.1:8080/ y ya debemos de tener el servidor corriendo

La creacin de modelos
Ahora que su entorno - un "proyecto" - est configurado, ya est listo para empezar a hacer el trabajo.
Cada aplicacin se escribe en Django consiste en un paquete de Python que sigue a una cierta convencin. Django viene con una
utilidad que genera automticamente la estructura de directorios bsica de una aplicacin, para que pueda centrarse en la escritura de
cdigo en lugar de crear directorios.
Creamos nuestra primera aplicacin, por lo pronto junto a manage.py

$ python manage.py startapp encuestas


El primer paso para escribir una aplicacin Web de base de datos en Django es definir sus modelos - esencialmente, su diseo de base
de datos, con metadatos adicionales.

Pregunta y Opcion. Una pregunta tiene una pregunta


Opcion tiene dos campos: el texto de la eleccin y un recuento de votos. Cada opcin se

En nuestra sencilla aplicacin encuesta, vamos a crear dos modelos:


y una fecha de publicacin. Una
asocia con una

pregunta.

Estos conceptos estn representados por las clases de Python simples. Editar el archivo de
que se ve as:

encuestas/models.py

from django.db import models


class Pregunta(models.Model):
pregunta_texto = models.CharField(max_length=200)
public_fech = models.DateTimeField('fecha publicado')
class Opcion(models.Model):
pregunta = models.ForeignKey(Pregunta)
opcion_texto = models.CharField(max_length=200)

encuestas/models.py por lo

votos = models.IntegerField(default=0)
nos falta decirle a Django que tenemos una aplicacin nueva, esto lo hacemos con:

miproyecto / settings.py

INSTALLED_APPS = (
'Django.contrib.admin',
'Django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'encuestas',
)
Le decimos a django que hicimos modificaciones en el modelo con:

$ python manage.py makemigrations encuestas


Ya esta, ahora incluso podramos ver nuestra bd en mysql con:

$ python manage.py sqlmigrate encuestas 0001


Escribimos nuevamente migrar para crear los modelos en cuadro de la base de datos

$ python manage.py migrate


Jugando con la API
Ahora, vamos a saltar en la terminal de Python interactiva y jugar con la API gratuita Django te da. Para invocar el shell de Python,
utilice este comando:

$ python manage.py shell


Importamos el django

>>> import django


>>> django.setup()
>>> from encuestas.models import Pregunta, Opcion
modelo de la bd.

# importamos las clases del

# consultar preguntas.
>>> Pregunta.objects.all()
[]
# Crear una pregunta.
# para la fecha necesitaremos importar timezone
>>> from django.utils import timezone
>>> q = Pregunta(pregunta_texto="estoy haciendo bien", publi_fech=timezone.now())
# guardamos los valores en q y luego lo guardamos.
>>> q.save()
# preguntamos el id, deveria de ser 1
>>> q.id
1

# para ver los atrivutos


>>> q.pregunta_texto
"estoy hacienda bien"
>>> q.publi_fech
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# cambiar los atributos del valor y guardar
>>> q.pregunta_texto = "otra pregunta
>>> q.save()
# imprimir todas las preguntas de la bd
>>> Pregunta.objects.all()
[<Question: Question object>]

<Pregunta: objeto Question>. Es, absolutamente, una representacin poco til de este
de preguntas (en el archivo de encuestas / models.py) y la
adicin de un __str__()mtodo para la Pregunta y Eleccin:
Espera un minuto

objeto. Vamos a arreglar eso editando el modelo

encuestas/models.py
from django.db import models
class Pregunta(models.Model):
# ...
def __str__(self):
return self.pregunta_texto
class Opcion(models.Model):
# ...
def __str__(self):
return self.opcion_texto

# __unicode__ on Python 2

# __unicode__ on Python 2

--------------------------del inicio y del fin----------------------

>>> from encuestas.models import Pregunta, Opcion #


>>> Pregunta.objects.all() # funciona las funciones
__str__. >>> Pregunta.objects.filter(id=1) >>>
Pregunta.objects.filter(pregunta_texto__startswith='otr
a') # probando funcin creados recien >>> from
django.utils import timezone >>> current_year =
timezone.now().year >>>
Pregunta.objects.get(publi_fech__year=current_year) si
funciona correctamente. >>> Pregunta.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# no existen mas registros. >>>
Pregunta.objects.get(pk=1) <Question: What's up?> #
asignamos a q el objeto >>> q =
Pregunta.objects.get(pk=1) >>>
q.was_published_recently() True # nos confirma que q
se encuentra dentro de ltimos publicados >>> q =
Pregunta.objects.get(pk=1) # para conocer opciones y
aun no hay. >>> q.opcion_set.all() [] # creamos 3

opciones. >>> q.opcion_set.create(opcion_texto='No


mucho', votos=0) se creo >>>
q.opcion_set.create(opcion_texto='el cielo',
votos=0)<Choice: The sky> >>> c =
q.opcion_set.create(opcion_texto='a jakear', votos=0)
# lo guardamos en c. >>> c.pregunta y accedemos a las
opciones. >>> q.opcion_set.all() y vemos nuestras 3
opciones >>> q.opcion_set.count() 3 # cuentra nuestras
opciones. >>>
Opcion.objects.filter(pregunta__publi_fech__year=curren
t_year) las opciones para el filtrado de las opciones
en fecha de pregunta. Se usa delete para borrar >>> c =
q.opcion_set.filter(opcion_texto__startswith='a
jakear') >>> c.delete()
creando el sitio de administracin

Creacin de un usuario admin


Primero tendremos que crear un usuario que puede iniciar sesin en el sitio de
administracin. Ejecute el siguiente comando:

$ python manage.py createsuperuser


ponemos el nombre del admin

Username: root
Onemos una direccin de correo

Email address: admin@example.com


Y para finalizar un pasword 2 veces:

Password: ********** Password (again): *********


Superuser created successfully.
inicie el servidor de desarrollo
El sitio de administracin de Django est activada por defecto. Vamos a empezar el servidor de
desarrollo y explorarlo.

$ Python manage.py runserver

Ahora, abra un navegador Web y vaya a "/ admin /" en su dominio local - por
ejemplo, http://127.0.0.1:8000/admin/ . Usted debe ver la pantalla de inicio de sesin del
administrador:

Haga la aplicacin sondeo modificable en el administrador


Pero dnde est nuestra aplicacin encuesta? No es mostrada en la pgina de ndice del administrador.
Slo una cosa que hacer: tenemos que decirle al administrador que los objetos de preguntas tienen una
interfaz de administracin. Para ello, abra el archivo de encuestas/admin.py, y editarlo para tener este
aspecto:
encuestas/admin.py

from django.contrib import admin


from encuestas.models import Pregunta
admin.site.register(Pregunta)

Personalizar el formulario de administracin


Tmese unos minutos para maravillarse con todo el cdigo que usted no tiene que escribir. Al
registrar el modelo de preguntas con admin.site.register (Pregunta), Django fue
capaz de construir una representacin formulario predeterminado. A menudo, usted querr
personalizar la forma en la forma de administracin se ve y funciona. Que va a hacer esto
dicindole Django las opciones que desee cuando se registra el objeto.
Vamos a ver cmo funciona esto reordenando los campos en el formulario de
edicin. Reemplace la lnea admin.site.register (Pregunta) con:
encuestas/admin.py

from django.contrib import admin


from polls.models import Pregunta
class QuestionAdmin(admin.ModelAdmin):
fields = ['publi_fech', 'pregunta_texto']
admin.site.register(Pregunta, PreguntaAdmin)

Esto no es impresionante, con slo dos campos, pero para las formas de administracin con
docenas de campos, la eleccin de un orden intuitivo es un detalle importante usabilidad.
Y hablando de formularios con docenas de campos, es posible que desee dividir el formulario de
arriba en fieldsets:
encuestas/admin.py

from django.contrib import admin


from encuestas.models import Pregunta

# Register your models here.


class PreguntaAdmin(admin.ModelAdmin):
fieldsets = [
(None,
['pregunta_texto']}),

{'fields':

('informacion de fecha', {'fields':


['publi_fech']}),
]

admin.site.register(Pregunta, PreguntaAdmin)
El primer elemento de cada tupla en fieldsets es el ttulo del grupo de campos. Esto es lo que
nuestra forma parece ahora:

Puede asignar clases HTML arbitrarios a cada conjunto de campos. Django proporciona una
clase "colapso" que muestra un conjunto de campos en particular colapsado inicialmente. Esto
es til cuando se tiene una forma larga que contiene una serie de campos que no son de uso
general:

polls/admin.py

from django.contrib import admin from encuestas.models


import Pregunta
class PreguntaAdmin(admin.ModelAdmin):
fieldsets = [
(None,
{'fields': ['pregunta_texto']}),
('informacion
fecha', {'fields': ['publi_fech'], 'classes':
['collapse']}),
]

Adicin de objetos relacionados


Bien, tenemos nuestra pgina de administracin pregunta. Pero una pregunta tiene
mltiples opciones, y la pgina de administracin no muestra opciones.
Sin embargo.
Hay dos maneras de resolver este problema. El primero es registrarse Eleccin con el
administrador tal como lo hicimos con la pregunta. Eso es fcil:
encuestas/admin.py

from django.contrib import admin from encuestas.models


import Opcion, Pregunta
# ...
admin.site.register(Opcion)
Ahora "elecciones" es una opcin disponible en la administracin de Django. El formulario "Aadir
eleccin" se ve as:

Como vemos cada Opcion esta relaciona con una pregunta esto es porque esta
relacionado con foreignKey
encuestas/admin.py

from django.contrib import admin


from encuestas.models import Opcion, Pregunta
class OpcionInline(admin.StackedInline):
model = Opcion
extra = 3
class PreguntaAdmin(admin.ModelAdmin):
fieldsets = [
(None,
{'fields': ['pregunta_texto']}),
('informacion
fecha', {'fields': ['publi_fecha'], 'classes':
['collapse']}),
]
inlines = [OpcionInline] admin.site.register(Pregunta,
PreguntaAdmin)
ahora tenemos las dos tablas juntadas y relacionadas directamente con pregunta

para no perder tanto espacion podemos cambiar la definicin de la clase por:


encuestas/admin.py

class OpcionInline(admin.TabularInline):
#...
Tambien podemos incluir lo que pusimos en el mtodo de los artculos recientes
encuestas/admin.py

class PreguntaAdmin(admin.ModelAdmin):
# ...
list_display = ('pregunta_texto', 'publi_fech',
'was_published_recently')
ahora podemos observar nuestra pagina de administracin de la siguiente manera:

podemos mejorar la parte de was_published_recently de la siguiente manera


encuestas/models.py

class Pregunta(models.Model):
# ...
def was_published_recently(self):
return self.publi_fech >= timezone.now() - datetime.timedelta(days=1)
was_published_recently.admin_order_field = 'publi_fech'
was_published_recently.boolean = True
was_published_recently.short_description = 'Publcado reciente?'
Edite el archivo de encuestas/admin.py y aadir una mejora a la pgina de lista de
cambios Pregunta: filtros utilizando el list_filter . Agregue la siguiente lnea
a PreguntaAdmin:

list_filter = ['publi_fech']
Eso aade una barra lateral "filtro" que permite a los usuarios filtrar la lista de cambios por el
campo publi_fech:

El tipo de filtro que se muestra depende del tipo de campo que est filtrando
en. Debido publi_fech es un DateTimeField , Django sabe dar opciones de filtro apropiadas:
"Cualquier fecha", "Hoy", "Los ltimos 7 das", "Este mes", "este ao."
Este se perfila bien. Vamos a aadir un poco de capacidad de bsqueda con solo aumentar la
siguiente linea:

search_fields = ['pregunta_texto']
Eso agrega un cuadro de bsqueda en la parte superior de la lista de cambios. Cuando alguien
entra en los trminos de bsqueda, Django buscar el campo pregunta_texto. Puede utilizar
tantos campos como desee - aunque, ya que utiliza una consulta como detrs de las escenas,
lo que limita el nmero de campos de bsqueda a un nmero razonable, ser ms fcil para su
base de datos para hacer la bsqueda.
Ahora tambin es un buen momento para sealar que las listas de cambios le dan paginacin
libre. El valor predeterminado es mostrar 100 elementos por pgina. Cambiar lista de
paginacin , cuadros de bsqueda , filtros , fecha-las jerarquas, y la columnaheader-ordenar todos trabajamos juntos como usted piensa que debera hacerlo.

Personaliza el aspecto de administracin y sentir


Est claro que tener "Django administracin" en la parte superior de cada pgina de
administracin es ridculo. Es slo el texto de marcador de posicin.
Eso es fcil de cambiar, sin embargo, el uso de sistema de plantillas de Django. La administracin
de Django se alimenta por s mismo Django, y sus interfaces utilizan el sistema de plantillas de
Django.

Personalizacin de las plantillas de su proyecto


Crear un directorio de Templates en el directorio del proyecto. Las plantillas pueden vivir en
cualquier parte de su sistema de archivos que Django puede acceder. (Django ejecuta como
cualquier usuario de su servidor se ejecuta.) Sin embargo, mantener sus plantillas en el proyecto
es una buena convencin a seguir.
Abra el archivo de configuracin (mysite / settings.py, recuerda) y aadir
un TEMPLATE_DIRS ajuste:
miproyecto/settings.py

TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]


TEMPLATE_DIRS es un iterable de directorios del sistema de archivos para comprobar al cargar
las plantillas de Django; es una ruta de bsqueda.
Ahora cree un directorio llamado administrador dentro de plantillas, y copie la
plantilla admin / base_site.html desde dentro del directorio de plantillas por defecto admin
Django en el cdigo fuente de Django en s (django / contrib / admin / templates) en
ese directorio.
Luego, simplemente editar el archivo y reemplazar con el nombre de su propio sitio como mejor
le parezca. Usted debe terminar con una lnea como:

<H1 id = "site-name">{% trans administracion de


encuestas %}></ h1>
Utilizamos este mtodo para ensearle cmo reemplazar las plantillas. En un proyecto real, es
probable que utilice la django.contrib.admin.AdminSite.site_header atributo para hacer
ms fcil esta personalizacin particular.

Este archivo de plantilla contiene una gran cantidad de texto como {% branding
bloque%} y {{title}}. La {{{% y etiquetas son parte del lenguaje de plantillas de
Django. Cuando Django hace admin / base_site.html, este lenguaje de la plantilla ser
evaluada para producir la pgina HTML final. No se preocupe si usted no puede hacer cualquier
sentido de la plantilla en este momento - vamos a profundizar en lenguaje de plantillas de Django
en el Tutorial 3.
Tenga en cuenta que ninguna de las plantillas de administracin por defecto de Django se puede
anular. Para anular una plantilla, hacer lo mismo que hizo con base_site.html - copiarlo desde
el directorio por defecto en su directorio personalizado, y realizar cambios.

Personalizacin de las plantillas de su aplicacin


Los lectores astutos preguntarn: Pero si TEMPLATE_DIRS estaba vaco por defecto, cmo fue
Django encontrar las plantillas de administracin por defecto? La respuesta es que, por defecto,
Django busca automticamente una templates /subdirectorio dentro de cada paquete de
aplicacin, para su uso como ayuda de emergencia (no se olvide que
django.contrib.admin es una aplicacin).
Nuestra aplicacin de encuesta no es muy complejo y no necesita las plantillas de encargo de
administrador. Pero si se hizo ms sofisticado y requiere la modificacin de plantillas de
administracin estndar de Django para algunas de sus funciones, sera ms sensato modificar
las plantillas de la aplicacin, en lugar de los del proyecto. De esa manera, usted podra incluir la
aplicacin urnas en cualquier nuevo proyecto y estar seguro de que iba a encontrar las plantillas
personalizadas que necesitaba.
Consulte la documentacin del cargador de plantillas para obtener ms informacin acerca de
cmo Django encuentra sus plantillas.

Personaliza la pgina de ndice del administrador


En una nota similar, es posible que desee personalizar la apariencia de la pgina de ndice de
administracin de Django.
Por defecto, muestra todas las aplicaciones en INSTALLED_APPS que han sido registradas en la
aplicacin de administracin, en orden alfabtico. Es posible que desee realizar cambios
significativos en el diseo. Despus de todo, el ndice es probablemente la pgina ms importante
de la administracin, y debe ser fcil de usar.
La plantilla de personalizar es admin / index.html. (Haga lo mismo que con admin /
base_site.html en la seccin anterior - copiarlo desde el directorio predeterminado al
directorio plantilla personalizada.) Edite el archivo, y usted ver que utiliza una variable de
template app_list. Esa variable contiene todas las aplicaciones Django instalado. En vez de
usar eso, puede Enlaces duro-cdigo de las pginas de administracin especficos objetar en
cualquier forma que usted piensa que es lo mejor.
-3-3-3-3-3333-33-33-333-33-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-3-33-3-3-3

Ahora trabajaremos con las vistas de las


encuestas
Filosofa

Una vista es un "tipo" de la pgina Web en la aplicacin Django que por lo general cumple una
funcin especfica y tiene una plantilla especfica. Por ejemplo, en una aplicacin de blog, es
posible que tenga los siguientes puntos de vista:

Blog homepage - muestra las ltimas pocas entradas.

Entrada pgina "detalle" - pgina para una sola entrada.

Pgina de archivo de base Ao - muestra todos los meses con entradas en el ao dado.

Pgina de archivo basado en Mes - muestra todos los das con las entradas en el mes dado.

Pgina de archivo basado Dia - muestra todas las entradas en el da determinado.

Comentario accin - publicar comentarios a una entrada dada.


En nuestra aplicacin de encuesta, tendremos los siguientes cuatro puntos de vista:

Pregunta pgina "index" - muestra las ltimas pocas preguntas.

Pregunta pgina "detalle" - muestra un texto de la pregunta, sin resultados, pero con una forma
de votar.

Pregunta "Results" - muestra los resultados para una pregunta en particular.

Accin Vote - se encarga de la votacin para una eleccin en particular en una pregunta en
particular.
En Django, pginas web y otros contenidos son entregados por las vistas. Cada vista est
representada por una funcin de Python sencilla (o mtodo, en el caso de puntos de vista
basados en la clase). Django elegir una vista mediante el examen de la URL que se solicita (para
ser ms precisos, la parte de la URL despus del nombre de dominio).
En su tiempo en la web que usted puede haber llegado a travs de este tipo de bellezas como
"ME2 / Sitios / dirmod.asp? Sid = & type = gen y mod = Core + Pages y gid =
A6CD4967199A42D9B65B1B". Usted estar encantado de saber que Django nos
permite patrones de URL mucho ms elegante que eso.
Un patrn de URL es simplemente la forma general de una URL - por ejemplo: / Archivo de

Noticias / <ao> / <mes> /.


Para llegar desde una direccin URL a una vista, Django usa lo que se conoce como 'URLconfs. A
Mapas URLconf patrones de URL (descritos como expresiones regulares) a vistas.
Este tutorial ofrece instrucciones bsicas en el uso de URLconfs, y usted puede referirse
a django.core.urlresolvers para ms informacin.

Escriba su primera vista


Vamos a escribir la primera vista. Abra el archivo de encuestas / views.py y ponga el
siguiente cdigo Python en ella:

encuestas / views.py

from django.http import HttpResponse


def index(request):
return HttpResponse("hola, mundo. Tu estas en
encuestas index.")

Esta es la vista ms simple posible en Django. Para llamar a la vista, tenemos que asignar a una
URL - y para esto necesitamos un URLconf.
Para crear una URLconf en el directorio de encuestas, cree un archivo llamado urls.py. Su
directorio de aplicacin debe ser similar a:

encuestas / __init__.py admin.py models.py tests.py


urls.py views.py
urls.py incluye el siguiente cdigo:

encuestas / urls.py

from django.conf.urls import, url


from encuestas import views
urlpatterns = patterns('',
name='index'),
)

url(r'^$', views.index,

El siguiente paso es apuntar la URLconf raz en el mdulo polls.urls. En miproyecto /


urls.py inserte un include () , dejndole con:

miproyecto / urls.py

from django.conf.urls import patterns, include, url


from django.contrib from admin

urlpatterns = patterns ('',


url ('encuestas ^ /' r, incluyen
('encuestas.urls')),
url (r '^ admin /', incluir (admin.site. urls)),
)
con esto podemos acceder http: // localhost: 8000 / encuestas / en el navegador, y usted debe
ver el texto "Hello, world. Ests en el ndice de encuestas. ", Que ha definido en la vista del

ndice.
La url () la funcin se pasa cuatro argumentos, se requieren dos: regex y vista, y dos
opcionales: kwargs ynombre. En este punto, vale la pena revisar lo que estos argumentos son para.
url () argumento: regex
El trmino "regex" es una forma corta de uso comn que significa "expresin regular", que es una sintaxis para
hacer coincidir patrones en cadenas, o en este caso, patrones de URL. Django comienza en la primera
expresin regular y hace su camino hacia abajo la lista, comparando la URL solicitada con cada expresin
regular hasta que encuentra uno que coincida.

Tenga en cuenta que estas expresiones regulares no buscan parmetros GET y POST, o el nombre de
dominio. Por ejemplo, en una solicitud de http://www.example.com/myapp/, la URLconf
buscar miaplicacion /. En una peticin a http://www.example.com/myapp/?page=3, la
URLconf tambin buscar miaplicacion /.
Si usted necesita ayuda con las expresiones regulares, consulte la entrada de Wikipedia y la documentacin de
la remdulo. Adems, el libro de O'Reilly "Mastering Regular Expressions" de Jeffrey Friedl es fantstico. En
la prctica, sin embargo, no es necesario ser un experto en expresiones regulares, ya que slo se necesita saber
cmo capturar patrones simples. De hecho, expresiones regulares complejas pueden tener malos resultados de
bsqueda, por lo que probablemente no deben confiar en el poder de las expresiones regulares.
Por ltimo, una nota de rendimiento: estas expresiones regulares son compilados la primera vez que se carga el
mdulo URLconf. Son sper rpido (siempre que las bsquedas no son demasiado complejos como se seal
anteriormente).
url () argumento: Vista
Cuando Django encuentra una coincidencia de expresiones regulares, Django llama a la funcin vista
especificada, con una HttpRequest objeto como primer argumento y los valores "capturados" de la
expresin regular como otros argumentos. Si la expresin regular utiliza capturas simples, los valores se pasan
como argumentos posicionales; si utiliza capturas con nombre, los valores se pasan como argumentos de
palabra clave. Vamos a dar un ejemplo de esto en un momento.
url () argumento: kwargs
Argumentos clave arbitrarias se pueden pasar en un diccionario a la vista de destino. No vamos a utilizar esta
caracterstica de Django en el tutorial.
url () argumento: nombre
El nombramiento de su URL permite referirse a ella de forma inequvoca de otras partes de Django
especialmente plantillas. Esta potente funcin le permite realizar cambios globales en los patrones de URL de
su proyecto, mientras que slo tocar un solo archivo.

Escribir ms vistas
Ahora vamos a aadir un poco ms de visitas a las encuestas / views.py. Estos puntos de
vista son un poco diferentes, porque toman un argumento:
Encuestas/views.py

def detail(request, pregunta_id):


return HttpResponse("tu estas viendo la pregunta
%s." % pregunta_id)
def results(request, pregunta_id):
response = "tu estas viendo el resultado de %s."
return HttpResponse(response % pregunta_id)
def vote(request, pregunta_id):
return HttpResponse("estas botando en la pregunta
%s." % pregunta_id)
Alambre estos nuevos puntos de vista en el mdulo encuestas.urls aadiendo la siguiente url
() llama:
encuestas/urls.py

from django.conf.urls import patterns, url


from encuestas import views
urlpatterns = patterns('',
# ex: /encuestas/
url(r'^$', views.index, name='index'),
# ex: /encuesta/5/
url(r'^(?P<pregunta_id>\d+)/$', views.detail,
name='detail'),
# ex: /encuestas/5/resultado/
url(r'^(?P<pregunta_id>\d+)/results/$',
views.results, name='results'),
# ex: /encuestaa/5/vote/
url(r'^(?P<pregunta_id>\d+)/vote/$', views.vote,
name='vote'),
)
Echa un vistazo en su navegador, en "/ encuestas / 34 /". Se va a ejecutar el mtodo
de detalle () y mostrar lo que sea ID que usted proporciona en la URL. Pruebe "/ encuestas /
34 / resultados /" y "/ encuestas / 34 / voto /" demasiado - stos se mostrarn los resultados de
marcador de posicin y las pginas de votacin.
Cuando alguien solicita una pgina de su sitio Web - por ejemplo, "/ encuestas / 34 /", Django
cargar el mdulo miproyecto.urls Python porque est apuntado por
el ROOT_URLCONF ajuste. Encuentra las urlpatterns variables con nombre y atraviesa las
expresiones regulares en orden. El include() funciones que estamos usando simplemente
hacer referencia a otros URLconfs. Tenga en cuenta que las expresiones regulares para
los include() funciones no tienen un $ (personaje partido final de la cadena), sino ms bien
una barra final. Siempre encuentros Django include () , se corta la que sea parte de la URL
igualado hasta ese momento y enva la cadena restante a la URLconf incluida para su posterior
procesamiento.
La idea detrs de include() es hacer que sea fcil de conectar URLs-and-play. Desde las
encuestas estn en su propio URLconf (encuestas/urls.py), que pueden ser colocados bajo
"/encuestas /", o en "/ fun_encuestas /", o en "/contenido /encuestas /", o cualquier otra raz
camino, y la aplicacin seguir funcionando.
Esto es lo que sucede si un usuario va a "/encuestas /34 /" en este sistema:

Django se encuentra el partido en el '^encuestas/'

Entonces, Django quitarse el texto correspondiente ("encuestas/") y enviar el resto del texto
- "34/" - a URLconf los 'polls.urls' para su posterior procesamiento que coincide con r '^
(P<pregunta_id>\d+)/$ 'que resulta en una llamada al detalle() ver de este modo:

detail(request=<HttpRequest object>,
pregunta_id='34')

El pregunta_id = '34 parte "viene de (?P<pregunta_id>\d+). El uso de


parntesis en torno a un patrn de "captura" el texto que coincide con ese patrn y lo
enva como argumento a la funcin de vista;? P <pregunta_id> define el nombre
que se utilizar para identificar el patrn emparejado; y \d+ es una expresin regular

para que coincida con una secuencia de dgitos (es decir, un nmero).
Debido a que los patrones de URL son expresiones regulares, realmente no hay lmite a lo
que puedes hacer con ellos. Y no hay necesidad de aadir URL, hay cosas tales
como Html - a menos que usted desea, en cuyo caso se puede hacer algo como esto:

(r'^encuestas/latest\.html$',
'encuestas.views.index'),

Pero, no hagas eso. Es una tontera. :D

Escribe vistas que realmente hacen algo


Cada punto de vista es responsable de hacer una de dos cosas: devolver
un HttpResponse objeto que contiene el contenido de la pgina solicitada, o lanzar una
excepcin, como Http404 . El resto depende de usted.
Tu punto de vista puede leer registros de una base de datos o no. Se puede utilizar un sistema de
plantillas como Django - o un sistema de plantillas Python de terceros - o no. Puede generar un
archivo PDF, XML de salida, crear un archivo ZIP en la marcha, lo que quieras, usando cualquier
librera de Python que quieras.
Todo lo que Django quiere es que HttpResponse. O una excepcin.
Porque es conveniente, utilicemos APIs apropia de base de datos de Django, que cubrimos
en Tutorial 1 He aqu una pualada en una vista nueva index (), que muestra las ltimas 5
preguntas de la encuesta en el sistema, separados por comas, de acuerdo a la fecha de
publicacin:
encuestas/views.py

#
from polls.models import Question
def index(request):
latest_pregunta_list =
Pregunta.objects.order_by('-publi_fech')[:5]
output = ', '.join([p.pregunta_texto for p in
latest_pregunta_list])

return HttpResponse(output)
Hay un problema aqu, sin embargo: el diseo de la pgina est codificado en la vista. Si
desea cambiar la apariencia de la pgina, tendrs que editar el cdigo Python. As que vamos
a usar el sistema de plantillas de Django para separar el diseo de Python mediante la
creacin de una plantilla que la visin puede utilizar.
En primer lugar, cree un directorio llamado templates en la carpeta de encuestas Django
buscar plantillas ah.
De Django TEMPLATE_LOADERS configuracin contiene una lista de callables que saben cmo
importar plantillas de diversas fuentes. Uno de los valores por defecto
es django.template.loaders.app_directories.Loader que busca una "plantillas"
subdirectorio en cada uno de los INSTALLED_APPS - as es como Django sabe encontrar las
plantillas de encuestas a pesar de que no modific TEMPLATE_DIRS , como lo hicimos
en Tutorial 2 .
Dentro del directorio de plantillas que acaba de crear, cree otro directorio llamado encuestas, y
dentro de esa crear un archivo llamado index.html. En otras palabras, la plantilla debe estar
enlas encuestas / templates / encuestas / index.html. Debido a la forma en el
cargador de plantillas app_directoriesfunciona como se describe ms arriba, puede hacer
referencia a esta plantilla dentro de Django simplemente como encuestas / index.html.
Coloque el siguiente cdigo en la plantilla:
encuestas/templates/encuestas/index.html

{% if latest_pregunta_list %}
<ul>
{% for pregunta in latest_pregunta_list %}
<li><a href="/encuestas/{{ pregunta.id }}/">{{
pregunta.pregunta_texto }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>no hay encuestas disponibles.</p>
{% endif %}
Ahora vamos a actualizar nuestra vista del ndice en las encuestas/ views.py utilizar la
plantilla:

encuestas/views.py

from django.http import HttpResponse

from django.template import RequestContext, loader


from encuestas.models import Pregunta

def index(request):
latest_pregunta_list = Pregunta.objects.order_by('publi_fech')[:5]
template =
loader.get_template('encuestas/index.html')
context = RequestContext(request, {
'latest_pregunta_list': latest_pregunta_list,
})
return HttpResponse(template.render(context))
Ese cdigo carga las plantillas llamado encuestas/index.html y la pasa de un contexto. El
contexto es un mapeo plantilla diccionario nombres de variables a objetos Python.
Cargue la pgina apuntando desde su navegador en "/ encuestas /", y usted debera ver una lista
con vietas que contiene el "Qu pasa" pregunta del Tutorial 1. el enlace apunta a la pgina de
detalles de la cuestin.

Un atajo: render()
Es un lenguaje muy comn para cargar una plantilla, llenar un contexto y devolver
un HttpResponse objeto con el resultado de la plantilla mostrada. Django proporciona un
atajo. Aqu est la vista del ndice completo (), reescrito:
encuestas/views.py

from django.shortcuts import render


from encuestas.models import Pregunta

def index(request):
latest_pregunta_list =
Pregunta.objects.all().order_by('-publi_fech')[:5]
context = {'latest_pregunta_list':
latest_pregunta_list}

return render(request,'encuestas/index.html',
context)
Tenga en cuenta que una vez que hemos hecho esto en todos estos puntos de vista, ya no
necesitamos importarloader , RequestContext y HttpResponse (usted querr
mantener HttpResponse si an tiene los mtodos de cdigo auxiliar para los detalles,
resultados y voto).
El render() funcin toma el objeto de solicitud como primer argumento, un nombre de plantilla
como su segundo argumento y un diccionario como opcional tercer argumento. Devuelve
un HttpResponse objeto de la plantilla dada prestados con el contexto dado.

Crear a un error 404


Ahora, vamos a abordar la vista detalle de la pregunta - la pgina que muestra el texto de la
pregunta para una encuesta determinada. Aqu est la vista:
encuestas/views.py

from django.http import Http404


from django.shortcuts import render
from polls.models import Question # ...
def detail(request, question_id):
try:
pregunta = Pregunta.objects.get(pk=pregunta_id)
except Pregunta.DoesNotExist:
raise Http404
return render(request,
'encuestas/detail.html', {'pregunta': pregunta})
El get_object_or_404 () funcin toma un modelo Django como su primer argumento y un
nmero arbitrario de argumentos de palabra clave, la cual pasa a la get () la funcin de
gerente de la modelo. Plantea Http404 si el objeto no existe.
Tambin hay un get_list_or_404 () funcin, que funciona igual
de get_object_or_404() - excepto por el uso del filtro() en lugar
de

get() . Plantea Http404 si la lista est vaca.

Utilice el sistema de plantillas


Volver a la vista de detalle() para nuestra aplicacin de encuesta. Teniendo en cuenta
la cuestin variable de contexto, esto es lo que la plantilla
de encuestas/detail.html podra ser:
encuestas/templates/encuestas/detail.html

<h1>{{ pregunta.pregunta_texto }}</h1> <ul> {% for


opcion in opcion.opcion_set.all %}
<li>{{
opcion.opcion_texto }}</li> {% endfor %} </ul>
El sistema de plantilla utiliza la sintaxis con punto-de bsqueda para acceder a los atributos de variable. En el
ejemplo de {{ pregunta.pregunta_texto }}, primero Django realiza una consulta de diccionario

sobre la pregunta objeto. De no ser as, se trata de una bsqueda de atributos - que trabaja, en este caso. Si
lookup atributo haba fallado, hubiera intentado un ndice de lista.
Mtodo insultos sucede en el {% for %} de bucle: pregunta.opcion_set.all se interpreta como la
pregunta.opcion_set.all cdigo Python(), que devuelve un iterable de objetos opcion y es
adecuado para su uso en la etiqueta {% for %}.

Extraccin de URLs codificadas en plantillas


Recuerde, cuando escribimos el enlace a una pregunta en la plantilla de las
encuestas/index.html, el enlace fue parcialmente codificado as:

<li><a href="/encuestas/{{ pregunta.id }}/">{{


pregunta.pregunta_texto }}</a></li>
El problema con este enfoque hardcoded, estrechamente unida es que se convierte en un reto para
cambiar las URL de los proyectos con una gran cantidad de plantillas. Sin embargo, como ha definido
el nombre del parmetro en la url() funciones en el mdulo encuestas.urls, puede eliminar la
dependencia de rutas URL especficas definidas en las configuraciones de direccin URL mediante
el {% url%} etiqueta de plantilla:

<li><a href="{% url 'detalle' pregunta.id %}">{{


pregunta.pregunta_texto }}</a></li>
La forma en que esto funciona es por buscar la definicin URL como se especifica en el
mdulo encuestas.urls. Usted puede ver exactamente donde se define el nombre de la URL de
'detail' a continuacin:

...
# the 'name' value as called by the {% url %} template
tag
url(r'^(?P<pregunta_id>\d+)/$', views.detail,
name='detail'),
...
Si desea cambiar la direccin URL de la vista encuestas detalle a otra cosa, tal vez a algo as como
encuestas / detalles / 12 / en lugar de hacerlo en la plantilla (o plantillas) que iba a cambiar
en las encuestas/urls.py:

...
# cambiamor la URL de acceso
url(r'^specifics/(?P<question_id>\d+)/$', views.detail,
name='detail'),

...
Namespacing nombres de URL
El proyecto tutorial tiene una sola aplicacin, las encuestas. En proyectos reales de Django,
puede haber cinco, diez, veinte o ms aplicaciones. Cmo Django diferenciar los nombres de
URL entre ellos? Por ejemplo, la aplicacin de encuestas tiene una vista de detalle, y
tambin podra hacerlo una aplicacin en el mismo proyecto que es para un blog. Cmo hacer
para que Django sabe que la vista de aplicaciones para crear una url cuando se utiliza el {%
url%} etiqueta de plantilla?
La respuesta es agregar espacios de nombres a tu URLconf raz. En el archivo de proyecto /
urls.py, seguir adelante y cambiar para incluir los espacios de nombre:
miproyecto/urls.py

from django.conf.urls import patterns, include, url


from django.contrib import admin

urlpatterns = patterns('',
url(r'^encuestas/', include('encuestas.urls',
namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
)
Ahora cambia su urls/ templates index.html desde:
encuestas/templates/encuestas/index.html

<li><a href="{% url 'detail' pregunta.id %}">{{


pregunta.pregunta_texto }}</a></li>
para sealar en la vista de detalle de namespace:
encuestas/templates/encuestas/index.html

<li><a href="{% url 'polls:detail' pregunta.id %}">{{


pregunta.pregunta_texto }}</a></li>
----------------------- 04 ---------------------------------------Escribir un sencillo formulario
Vamos a actualizar nuestra plantilla detalle sondeo ("encuestas / detail.html") desde el ltimo
tutorial, por lo que la plantilla contiene una etiqueta <form> elemento:

encuestas/templates/encuestas/detail.html

<h1>{{ pregunta.pregunta_texto }}</h1>

{% if error_message %}<p><strong>{{ error_message


}}</strong></p>{% endif %}
<form action="{% url 'polls:vote' pregunta.id %}"
method="post">
{% csrf_token %}
{% for opcion in pregunta.opcion_set.all %}
<input type="radio" name="opcion" id="opcion{{
forloop.counter }}" value="{{ opcion.id }}" />
<label for="opcion{{ forloop.counter }}">{{
opcion.opcion_texto }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
Tambin hemos creado una aplicacin de relleno de la funcin voto (). Vamos a crear una
versin real. Agregue lo siguiente a las encuestas/views.py:
lls/views.py

from django.shortcuts import get_object_or_404, render


from django.http import HttpResponseRedirect,
HttpResponse
from django.core.urlresolvers import reverse
from polls.models import Opcion, Pregunta
# ...
def vote(pregunta, pregunta_id):
p = get_object_or_404(Pregunta, pk=pregnta_id)
try:
selected_opcion =
p.opcion_set.get(pk=request.POST['opcion'])
except
(KeyError, Opcion.DoesNotExist):
# Redisplay
the question voting form.
return
render(request, 'polls/detail.html', {
'question': p,
'error_message': "You didn't
select a choice.",
})
else:
selected_opcion.votos += 1

selected_choice.save()
# Always return an
HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted
twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results',
args=(p.id,)))
Este cdigo incluye un par de cosas que no hemos cubierto todava en este tutorial:

request.POST es un objeto similar a un diccionario que le permite acceder a los datos presentados por el
nombre de la clave. En este caso, request.POST ["opcion"] devuelve el identificador de la opcin
seleccionada, como una cadena. request.POST valores son siempre cadenas.
Tenga en cuenta que Django tambin ofrece request.GET para acceder a datos GET de la misma manera pero estamos usando explcitamente request.POST en nuestro cdigo, para garantizar que los datos slo se
altera a travs de una llamada POST.

request.POST ['opcion'] elevar KeyError si la eleccin no fue proporcionada en los datos


POST. El cdigo comprueba anteriores para KeyError y vuelve a mostrar la forma de la pregunta con un
mensaje de error si no se le da opcin.

Despus de incrementar el recuento de la eleccin, el cdigo devuelve un HttpResponseRedirect en


lugar de una normal de HttpResponse . HttpResponseRedirect toma un solo argumento: la URL a la
que se redirige al usuario (ver el siguiente punto de cmo construimos la URL en este caso).
Como el comentario Python arriba seala, siempre debe devolver un HttpResponseRedirect despus de
tratar con xito con datos POST. Este consejo no es especfico de Django; es slo una buena prctica de
desarrollo Web.

Estamos utilizando la reverse() funcin en la HttpResponseRedirect constructor en

este ejemplo. Esta funcin ayuda a evitar tener que codificar una URL en la funcin de vista. Se
da el nombre de la vista que queremos pasar el control de y la parte variable del patrn de URL
que apunta a esa vista. En este caso, el uso de la URLconf hemos creado en el Tutorial 3,
este reverse() llamada devolver una cadena como

'/polls/3/results/'
... Donde el 3 es el valor de p.id. Esta URL redirigida entonces llame a la
vista 'resultados' para mostrar la pgina final.
Como se mencion en el Tutorial 3, es una peticin HttpRequest objeto. Para ms
informacin sobre HttpRequestobjetos, consulte la solicitud y la documentacin respuesta .
Despus alguien vota en una pregunta, la opinin de voto() redirige a la pgina de resultados
para la pregunta. Vamos a escribir ese punto de vista:
encuestas/views.py

from django.shortcuts import get_object_or_404, render


def results(request, pregunta_id):
pregunta = get_object_or_404(Pregunta,
pk=pregunta_id)
return render(request,
'encuestas/results.html', {'pregunta': pregunta})

Esto es casi exactamente el mismo que la vista de detalle () desde Tutorial 3 . La nica
diferencia es el nombre de la plantilla. Vamos a arreglar esta redundancia despus.
Ahora, crear una plantilla de encuestas/results.html:
encuestas/templates/polls/results.html

<h1>{{ pregunta.pregunta_texto }}</h1> <ul> {% for


opcion in pregunta.opcion_set.all %}
<li>{{
opcion.opcion_texto }} -- {{ opcion.votos }} voto{{
opcion.votos|pluralize }}</li> {% endfor %} </ul> <a
href="{% url 'polls:detail' pregunta.id %}">Votar
denuevo?</a>

Ahora, vaya a / encuestas / 1 / en el navegador y voto en la pregunta. Usted debe ver una pgina de
resultados que se actualiza cada vez que vote. Si usted enva el formulario sin haber elegido una opcin,
debera ver el mensaje de error.

Utilice las vistas genricas: Menos cdigo es mejor


El detalle() (de Tutorial 3 ) y los resultados () vistas son estpidamente sencillo - y,
como se mencion anteriormente, redundante. El ndice () vista (tambin de Tutorial 3), que
muestra una lista de encuestas, es similar.
Estos puntos de vista representan un caso comn de desarrollo Web bsica: datos obtenidos de
la base de datos de acuerdo con un parmetro pasado en la URL, la carga de una plantilla y
devolver la plantilla renderizada. Porque esto es tan comn, Django proporciona un atajo,
llamado el "vistas genricas" del sistema.
Vistas genricas patrones comunes abstractos hasta el punto en el que ni siquiera necesidad de
escribir cdigo Python para escribir una aplicacin.
Convirtamos nuestra aplicacin encuesta para utilizar el sistema de puntos de vista genrico, por
lo que podemos eliminar un montn de nuestro propio cdigo. Tendremos que tomar algunas
medidas para hacer la conversin. Lo haremos:
1. Convertir la URLconf.
2. Eliminar algunos de los antiguos, vistas que no sean necesarios.
3. Dar a conocer nuevos puntos de vista sobre la base de las vistas genricas de Django.