<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://es.wikieducator.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
		<id>https://es.wikieducator.org/index.php?action=history&amp;feed=atom&amp;title=Curso_Python_DGA_2011%2Fdjango%2Fcontenidos%2Fvistas</id>
		<title>Curso Python DGA 2011/django/contenidos/vistas - Historial de revisiones</title>
		<link rel="self" type="application/atom+xml" href="https://es.wikieducator.org/index.php?action=history&amp;feed=atom&amp;title=Curso_Python_DGA_2011%2Fdjango%2Fcontenidos%2Fvistas"/>
		<link rel="alternate" type="text/html" href="https://es.wikieducator.org/index.php?title=Curso_Python_DGA_2011/django/contenidos/vistas&amp;action=history"/>
		<updated>2026-06-19T05:26:49Z</updated>
		<subtitle>Historial de revisiones para esta página en el wiki</subtitle>
		<generator>MediaWiki 1.23.14</generator>

	<entry>
		<id>https://es.wikieducator.org/index.php?title=Curso_Python_DGA_2011/django/contenidos/vistas&amp;diff=5215&amp;oldid=prev</id>
		<title>Lmorillas: Página creada con '== Creación de la interfaz pública == En la filosofía de Django una vista es un tipo de página web que sirve para una función específica y tiene una plantilla específica.…'</title>
		<link rel="alternate" type="text/html" href="https://es.wikieducator.org/index.php?title=Curso_Python_DGA_2011/django/contenidos/vistas&amp;diff=5215&amp;oldid=prev"/>
				<updated>2011-08-24T06:25:44Z</updated>
		
		<summary type="html">&lt;p&gt;Página creada con &amp;#039;== Creación de la interfaz pública == En la filosofía de Django una vista es un tipo de página web que sirve para una función específica y tiene una plantilla específica.…&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Página nueva&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Creación de la interfaz pública ==&lt;br /&gt;
En la filosofía de Django una vista es un tipo de página web que sirve para una función específica y tiene una plantilla específica. Por ejemplo en un blog podemos tener:&lt;br /&gt;
* La página inicial del Blog (muestra las últimas entradas)&lt;br /&gt;
* El detalle de una entada&lt;br /&gt;
* Página de las entradas por ffechas (día, mes, año) &lt;br /&gt;
* Comentarios&lt;br /&gt;
&lt;br /&gt;
En la aplicación de las encuestas:&lt;br /&gt;
* Página índice de Encuestas, que muestre las últimas encuestas&lt;br /&gt;
* Página de detalle de encuestas: Muestra una pregunta con el formulario para votar&lt;br /&gt;
* Página de resultados de una encuesta.&lt;br /&gt;
&lt;br /&gt;
Philosophy&lt;br /&gt;
A view is a “type” of Web page in your Django application that generally serves a specific function and has a specific template. For example, in a Weblog application, you might have the following views:&lt;br /&gt;
&lt;br /&gt;
Blog homepage – displays the latest few entries.&lt;br /&gt;
Entry “detail” page – permalink page for a single entry.&lt;br /&gt;
Year-based archive page – displays all months with entries in the given year.&lt;br /&gt;
Month-based archive page – displays all days with entries in the given month.&lt;br /&gt;
Day-based archive page – displays all entries in the given day.&lt;br /&gt;
Comment action – handles posting comments to a given entry.&lt;br /&gt;
In our poll application, we’ll have the following four views:&lt;br /&gt;
&lt;br /&gt;
En Django cada vista la gestiona una fución.&lt;br /&gt;
&lt;br /&gt;
=== Diseño de URLs===&lt;br /&gt;
El primer paso para escribir una vista es diseñar la estructura de la URL. Django asocia una URL con código Python mediante el módulo URLconf.&lt;br /&gt;
&lt;br /&gt;
Las urls se controlan con la variable urlpatterns, que es una secuencia de tuplas con el siguiente formato:&lt;br /&gt;
 (expresión regular, function python [, diccionario opcional])&lt;br /&gt;
Django busca por orden y lanza la primera función que cumple el patrón. Cuando Django la encuentra, llama a la función Python con un objeto '''HttpRequest''' como primer argumento, valores capturados de la url como argumentos por clave y otros argumentos opcionales (tercer elemento de la tupla)&lt;br /&gt;
&lt;br /&gt;
Al crear el proyecto se crea un URLconf por defecto en '''urls.py''' Esto se configura en settings.py (ver variable ROOT_URLCONF)&lt;br /&gt;
&lt;br /&gt;
ROOT_URLCONF = 'mysite.urls'&lt;br /&gt;
&lt;br /&gt;
Ejemplo. Edita urls.py como el siguiente ejemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.conf.urls.defaults import patterns, include, url&lt;br /&gt;
&lt;br /&gt;
from django.contrib import admin&lt;br /&gt;
admin.autodiscover()&lt;br /&gt;
&lt;br /&gt;
urlpatterns = patterns('',&lt;br /&gt;
    (r'^encuestas/$', 'encuestas.views.index'),&lt;br /&gt;
    (r'^encuestas/(?P&amp;lt;encuesta_id&amp;gt;\d+)/$', 'encuestas.views.detalle'),&lt;br /&gt;
    (r'^encuestas/(?P&amp;lt;encuesta_id&amp;gt;\d+)/resultado/$', 'encuestas.views.resultado'),&lt;br /&gt;
    (r'^encuestas/(?P&amp;lt;encuesta_id&amp;gt;\d+)/votar/$', 'encuestas.views.votar'),&lt;br /&gt;
    url(r'^admin/', include(admin.site.urls)),&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Según nuestro ejemplo si el usuario pide&lt;br /&gt;
 /encuestas/23&lt;br /&gt;
&lt;br /&gt;
Django ejecutará &lt;br /&gt;
 detalle((request=&amp;lt;HttpRequest object&amp;gt;, encuesta_id='23')&lt;br /&gt;
  &lt;br /&gt;
Los paréntesis de la expresión regular capturan el texto que coincide con el patrón.&lt;br /&gt;
&lt;br /&gt;
El módulo URLconf compila las expresiones regulares para que se ejecuten más rápidas.&lt;br /&gt;
&lt;br /&gt;
=== Primera vista===&lt;br /&gt;
Todavía no hemos creado ninguna vista. Vamos a comprobar que el URLconf funciona bien.&lt;br /&gt;
 python manage.py runserver&lt;br /&gt;
Ve a &amp;quot;http://localhost:8000/encuestas/&amp;quot; con el navegador. Tenemos que ver el error de que la vista no existe.&lt;br /&gt;
&lt;br /&gt;
  Exception Type: 	ViewDoesNotExist&lt;br /&gt;
&lt;br /&gt;
Escribimos las vistas en '''encuestas/views.py'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.http import HttpResponse&lt;br /&gt;
&lt;br /&gt;
def index(request):&lt;br /&gt;
    return HttpResponse(u&amp;quot;Hola, este es el índice de las encuestas.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def detalle(request, encuesta_id):&lt;br /&gt;
    return HttpResponse(u&amp;quot;Estás viendo la encuesta %s.&amp;quot; % encuesta_id)&lt;br /&gt;
&lt;br /&gt;
def resultado(request, encuesta_id):&lt;br /&gt;
    return HttpResponse(u&amp;quot;Estás viendo el resultado de la encuesta %s.&amp;quot; % encuesta_id)&lt;br /&gt;
&lt;br /&gt;
def votar(request, encuesta_id):&lt;br /&gt;
    return HttpResponse(u&amp;quot;Estás votando la encuesta %s.&amp;quot; % encuesta_id)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Vistas que hacen algo ===&lt;br /&gt;
Ahora vamos a escribir vistas que hagan algo realmente&lt;br /&gt;
Las vistas tienen que devolver:&lt;br /&gt;
* El objeto HttpResponse con el contenido de la página solicitada o&lt;br /&gt;
* Una excepción (por ej. Http404)&lt;br /&gt;
&lt;br /&gt;
'''index'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
def index(request):&lt;br /&gt;
    # Extrae 5 últimas encuestas de la bbdd. Orden: la última primero.&lt;br /&gt;
    listado_ultimas = Encuesta.objects.all().order_by('-fecha_pub')[:5]&lt;br /&gt;
    # prepara el resultado para mostrarlo&lt;br /&gt;
    output = ', '.join([p.pregunta for p in listado_ultimas])&lt;br /&gt;
    return HttpResponse(output)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Problema: el diseño de la página está integrado en la vista. Si queremos cambiar el aspecto de la página, hay que editar código python. Idea: separar código y presentación usando el sistema de plantillas de Django:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.http import HttpResponse&lt;br /&gt;
from django.template import Context, loader&lt;br /&gt;
from encuestas.models import Encuesta&lt;br /&gt;
&lt;br /&gt;
def index(request):&lt;br /&gt;
    # Extrae 5 últimas encuestas de la bbdd. Orden: la última primero.&lt;br /&gt;
    listado_ultimas = Encuesta.objects.all().order_by('-fecha_pub')[:5]&lt;br /&gt;
    t = loader.get_template('encuestas/index.html')&lt;br /&gt;
    c = Context({&lt;br /&gt;
        'listado_ultimas': listado_ultimas,&lt;br /&gt;
        })&lt;br /&gt;
    return HttpResponse(t.render(c))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Primera plantilla ====&lt;br /&gt;
Es necesario crear la plantilla en una ruta incluida en TEMPLATE_DIRS. Editamos '''[directorio_plantillas]/encuestas/index.html&amp;quot; Por&amp;gt; seguridad no se extraen las plantillas de la raíz del proyecto.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
{% if listado_ultimas %}&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
    {% for encuesta in listado_ultimas %}&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/encuestas/{{ encuesta.id}}/&amp;quot;&amp;gt;{{ encuesta.pregunta }}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    {% endfor %}&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
{% else %}&lt;br /&gt;
    &amp;lt;p&amp;gt;No hay encuestas disponibles.&amp;lt;/p&amp;gt;&lt;br /&gt;
{% endif %}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Atajo: render_to_response()====&lt;br /&gt;
¿Para qué repetir tanto? Ya no es necesario importar loader, Context y HttpResponse.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.shortcuts import render_to_response&lt;br /&gt;
from encuestas.models import Encuesta&lt;br /&gt;
&lt;br /&gt;
def index(request):&lt;br /&gt;
    listado_ultimas = Encuesta.objects.all().order_by('-fecha_pub')[:5]&lt;br /&gt;
    return render_to_response('encuestas/index.html',&lt;br /&gt;
        {'listado_ultimas': listado_ultimas,})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Lanzando una respuesta 404 (no encontrado) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.shortcuts import render_to_response&lt;br /&gt;
from django.http import Http404&lt;br /&gt;
from encuestas.models import Encuesta&lt;br /&gt;
# ...&lt;br /&gt;
def detalle(request, encuesta_id):&lt;br /&gt;
    try:&lt;br /&gt;
        enc = Encuesta.objects.get(pk=encuesta_id)&lt;br /&gt;
    except Encuesta.DoesNotExist:&lt;br /&gt;
        raise Http404  # Si la encuesta no existe, lanza un httpresponse: 404&lt;br /&gt;
    return render_to_response('encuestas/detalle.html', {'encuesta': enc})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Creamos una plantilla para encuestas/detalle.html:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
{{encuesta}}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Resultado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ curl -I http://127.0.0.1:8000/encuestas/12/&lt;br /&gt;
HTTP/1.0 404 NOT FOUND&lt;br /&gt;
Date: Wed, 24 Aug 2011 05:27:20 GMT&lt;br /&gt;
Server: WSGIServer/0.1 Python/2.7.1+&lt;br /&gt;
Content-Type: text/html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Otro atajo: get_object_or_404()====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.shortcuts import render_to_response, get_object_or_404&lt;br /&gt;
# ...&lt;br /&gt;
def detalle(request, encuesta_id):&lt;br /&gt;
    enc = get_object_or_404(Encuesta, pk=encuesta_id)&lt;br /&gt;
    return render_to_response('encuestas/detalle.html', {'encuesta': enc})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
La función '''get_object_or_404()''' toma como primer argumento un modelo de Django y un número no determinado de argumentos por clave. Si el objeto no existe, lanza un Http404.&lt;br /&gt;
&lt;br /&gt;
Si buscamos una secuencia de objetos, podemos usar '''get_list_or_404()''', que usa filter() en lugar de get(). Lanza Http404 si la lista está vacía.&lt;br /&gt;
==== Escribir una vista 404 (página no encontrada) ====&lt;br /&gt;
Cuando DEBUG está activado, la vista 404 no se usa y Django muestra el error. &lt;br /&gt;
Cuando DEBUG está a False, va a buscar un template 404.html en la raíz del directorio de templates. Si no lo encuentra, lanza un Http500. También hay que escribir una plantilla para 500.html.&lt;br /&gt;
&lt;br /&gt;
Plantilla de detalle.html&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;{{ encuesta.pregunta }}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
{% for opcion in encuesta.opcion_set.all %}&lt;br /&gt;
    &amp;lt;li&amp;gt;{{ opcion.opcion }}&amp;lt;/li&amp;gt;&lt;br /&gt;
{% endfor %}&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
El sistema de plantillas usa la sintaxis del punto para accceder a los atributos. Fíjate en como usa el {% for %} y como accede a las opciones desde el objeto encuestas&lt;br /&gt;
 encuesta.opcion_set.all&lt;br /&gt;
equivale a &lt;br /&gt;
 encuesta.opcion_set.all()&lt;br /&gt;
Que devuelve el iterable que recorre el for.&lt;br /&gt;
&lt;br /&gt;
Más información en la [https://docs.djangoproject.com/en/1.3/topics/templates/ guía de plantillas]&lt;br /&gt;
&lt;br /&gt;
====Simplificando URLconfs ====&lt;br /&gt;
Podemos usar patrones para evitar repeticiones:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
urlpatterns = patterns('encuestas.views',&lt;br /&gt;
    (r'^encuestas/$', 'index'),&lt;br /&gt;
    (r'^encuestas/(?P&amp;lt;encuesta_id&amp;gt;\d+)/$', 'detalle'),&lt;br /&gt;
    (r'^encuestas/(?P&amp;lt;encuesta_id&amp;gt;\d+)/resultado/$', 'resultado'),&lt;br /&gt;
    (r'^encuestas/(?P&amp;lt;encuesta_id&amp;gt;\d+)/votar/$', 'votar'),&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
urlpatterns += patterns('',&lt;br /&gt;
    (r'^admin/', include(admin.site.urls)),)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
También se pueden desacoplar, para hacer más reutilizables las aplicaciones (aplicaciones pluggables)&lt;br /&gt;
Pasos:&lt;br /&gt;
* Movemos sitio_encuestas/urls.py a encuestas/urls.py&lt;br /&gt;
* Cambiamos sitio_encuestas/urls.py para eliminar las urls de encuestas e insertamos un include():&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.conf.urls.defaults import *&lt;br /&gt;
&lt;br /&gt;
from django.contrib import admin&lt;br /&gt;
admin.autodiscover()&lt;br /&gt;
&lt;br /&gt;
urlpatterns = patterns('',&lt;br /&gt;
    (r'^encuestas/', include('encuestas.urls')),&lt;br /&gt;
    (r'^admin/', include(admin.site.urls)),&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Así quedará encuestas/urls.py&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot; line=&amp;quot;GESHI_NORMAL_LINE_NUMBERS&amp;quot;&amp;gt;&lt;br /&gt;
from django.conf.urls.defaults import *&lt;br /&gt;
&lt;br /&gt;
urlpatterns = patterns('encuestas.views',&lt;br /&gt;
    (r'^$', 'index'),&lt;br /&gt;
    (r'^(?P&amp;lt;encuesta_id&amp;gt;\d+)/$', 'detalle'),&lt;br /&gt;
    (r'^(?P&amp;lt;encuesta_id&amp;gt;\d+)/resultado/$', 'resultado'),&lt;br /&gt;
    (r'^(?P&amp;lt;encuesta_id&amp;gt;\d+)/votar/$', 'votar'),&lt;br /&gt;
    )&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Como ahora tienen una ruta relativa, podemos instalar la aplicación en distintas URLs: /encuestas, /encuestas_alumnos, /encuestas_corporativas y la aplicación seguirá funcionando.&lt;/div&gt;</summary>
		<author><name>Lmorillas</name></author>	</entry>

	</feed>