Ver índice de contenidos del libro

9.5. Filtrado complejo con funciones adaptadoras

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.