Otra necesidad común es filtrar los objetos que se muestran en una página
listado por alguna clave en la URLconf. Anteriormente codificamos el nombre
del publisher en la URLconf, pero ¿qué pasa si queremos escribir una vista que
muestre todos los books por algún publisher arbitrario?. Podemos encapsular
la vista genérica object_list
para evitar escribir mucho código a mano. Como
siempre, empezamos escribiendo una URLconf.
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info),
(r'^books/(\w+)/$', books_by_publisher),
)
A continuación, escribiremos la vista books_by_publisher
:
from django.http import Http404
from django.views.generic import list_detail
from mysite.books.models import Book, Publisher
def books_by_publisher(request, name):
# Look up the publisher (and raise a 404 if it can't be found).
try:
publisher = Publisher.objects.get(name__iexact=name)
except Publisher.DoesNotExist:
raise Http404
# Use the object_list view for the heavy lifting.
return list_detail.object_list(
request,
queryset = Book.objects.filter(publisher=publisher),
template_name = "books/books_by_publisher.html",
template_object_name = "books",
extra_context = {"publisher" : publisher}
)
Esto funciona porque en realidad no hay nada en especial sobre las vistas
genéricas — son sólo funciones Python. Como cualquier función de vista,
las vistas genéricas esperan un cierto conjunto de argumentos y retornan
objetos HttpResponse
. Por lo tanto, es increíblemente fácil encapsular una
pequeña función sobre una vista genérica que realiza trabajo adicional antes (
o después; mira la siguiente sección) de pasarle el control a la vista
genérica.
Nota En el ejemplo anterior pasamos el publisher que se está mostrando
actualmente en el extra_context
. Normalmente esto es una buena idea en
wrappers de este tipo ya que permite a la plantilla saber qué objeto
"padre" esta siendo navegado en ese momento.