DJANGO - VISTAS GENERICAS

En esta sesión introducimos el uso de vistas genéricas basadas en clases de Django, que encapsulan de manera sencilla diversos patrones comunes en la lógica de vistas para una aplicación web. Detallaremos dos ejemplos comunes: la vista de lista (ListView) y la de detalle (DetailView).

Cargando video...

NOTA: Solo puedes ver una versión limitada del video a baja resolución, si quieres ver la versión completa por favor regístrate y obtén alguno de nuestros planes!

Descripción del Vídeo

Como hemos visto, el código o lógica de varias acciones puede ser sencillo y repetitivo (en nuestro ejemplo, en el listado, el detalle y los resultados), siguiendo un patrón simple:
Obtener información del modelo de BD (ya sea un solo objeto o una colección)
Colocar información en un diccionario (contexto), y
Usar una plantilla para mostrar la información

Django ofrece un mecanismo para manejar éstos y otros patrones comunes de manera sencilla: las vistas genéricas (basadas en clases).

Ilustraremos dos de las clases para vistas genéricas más usadas: la vista de lista (ListView) y la detallada (DetailView).
Código disponible en:
https://github.com/networkfaculty/Fundamentos-Django/releases/tag/d-2.3.5
curso/encuestas/urls.py

from django.conf.urls import url
from . import views
urlpatterns = [
# ej: /encuestas/
url(r'^$', views.VistaIndex.as_view(), name='index'),
# ej: /encuestas/5
# Las vistas detalladas genéricas esperan que el argumento se llame 'pk'
url(r'^(?P\d+)/$', views.VistaDetalle.as_view(), name='detalle'),
# ej: /encuestas/5/resultados
url(r'^(?P\d+)/resultados$', views.VistaResultados.as_view(), name='resultados'),
# ej: /encuestas/5/votar
url(r'^(?P\d+)/votar$', views.votar, name='votar'),
]

curso/encuestas/views.py

from .models import Pregunta, Opcion
from django.shortcuts import get_object_or_404, render
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.db.models import F
from django.core.urlresolvers import reverse
from django.views import generic
#def index(request):
#preguntas_recientes = Pregunta.objects.order_by('-fe_publicacion')[:5]
#context = {'preguntas_recientes': preguntas_recientes,
#'titulo': 'Listado de Encuestas' }
#return render(request, 'encuestas/index.html', context)
class VistaIndex(generic.ListView):
template_name = 'encuestas/index.html'
context_object_name = 'preguntas_recientes'
def get_queryset(self):
return Pregunta.objects.order_by('-fe_publicacion')[:5]
#def detalle(request, id_pregunta):
#pregunta = get_object_or_404( Pregunta, pk=id_pregunta )
#return render(request, 'encuestas/detalle.html', {'pregunta': pregunta})
class VistaDetalle(generic.DetailView):
model = Pregunta
template_name = 'encuestas/detalle.html'
def votar(request, id_pregunta):
pregunta = get_object_or_404( Pregunta, pk=id_pregunta )
try:
# Nos aseguramos de que el código de la opción recibida esté dentro de las
# opciones registradas para la pregunta
opcion_seleccionada = pregunta.opcion_set.get(pk=request.POST['opcion'])
# Incrementamos la cantidad de votos para la opción seleccionada, pero desde la
# base de datos directamente
# opcion_seleccionada.votos += 1 # Esto puede generar problemas en transacciones
# concurrentes
opcion_seleccionada.votos = F('votos') + 1
opcion_seleccionada.save()
# Nota: Lo anterior también podría escribirse de forma compacta como:
# opcion_seleccionada.update( votos = F('votos') + 1 )
# Luego de guardar exitosamente, redireccionamos a página de resultados.
# Utilizamos 'reverse' para obtener de manera reutilizable la URL de la vista a
# la que queremos redirigir al usuario.
return HttpResponseRedirect(reverse('encuestas:resultados',
kwargs={'id_pregunta': pregunta.id}))
except (KeyError, Opcion.DoesNotExist):
# En caso de un código incorrecto o faltante de opción, volver a mostrar el formulario
return render(request, 'encuestas/detalle.html', {
'pregunta': pregunta,
'mensaje_error': "Opción faltante o inválida",
})
#def resultados(request, id_pregunta):
#pregunta = get_object_or_404( Pregunta, pk=id_pregunta )
#return render(request, 'encuestas/resultados.html', {'pregunta': pregunta})
class VistaResultados(generic.DetailView):
model = Pregunta
template_name = 'encuestas/resultados.html'

Rating

Global

Ver video en playlist

comments powered by Disqus

Headshot of Juan Paredes

Juan Paredes

Ingeniero de Sistemas con amplia experiencia, especializado en el desarrollo y arquitectura de software.