2011-08-10 13 views
12

Estoy usando la vista genérica basada en clases de Django 1.3 para mostrar una lista de imágenes, pero quiero agregar un filtro que permita al usuario restringir los resultados mostrados.¿Cómo crear un formulario de filtro para una lista de objetos genéricos (clase) en Django?

Mis actuales trabajos de aproximación, pero se siente muy hacker:

class ImageFilterForm(ModelForm): 
    class Meta: 
     model = Image 

class ImageListView(ListView): 
    model = Image 

    def get_queryset(self): 
     qs = Image.objects.select_related() 
     for item in self.request.GET: 
      key, value = item, self.request.GET.getlist(item) 
      # ... Filtering here ... 
     return qs 

    def get_context_data(self, **kwargs): 
     context = super(ImageListView, self).get_context_data(**kwargs) 
     context['filter_form'] = ImageFilterForm(self.request.GET) 
     return context 

¿Hay mejores medios para añadir la costumbre de filtrar para una visión genérica?

Respuesta

20

Puedo utilizar el mismo enfoque, pero genérico, utilizando un mixin:

class FilterMixin(object): 

    def get_queryset_filters(self): 
     filters = {} 
     for item in self.allowed_filters: 
      if item in self.request.GET: 
       filters[self.allowed_filters[item]] = self.request.GET[item] 
     return filters 

    def get_queryset(self): 
     return super(FilterMixin, self).get_queryset()\ 
       .filter(**self.get_queryset_filters()) 


class ImageListView(FilterMixin, ListView): 

    allowed_filters = { 
     'name': 'name', 
     'tag': 'tag__name', 
    } 

    # no need to override get_queryset 

Esto permite especificar una lista de filtros aceptados, y que no tienen que corresponder a las palabras clave .filter() reales. A continuación, puede expandirla para apoyar un filtrado más complejo (separados por comas cuando se hace un filtro __in o __range es un ejemplo sencillo)

+1

acabo de encontrar la aplicación [django-filter] (https://github.com/alex/django-filter) y la combinó con su mixin. Creo que eso es lo suficientemente limpio para mí ;-) ¡Gracias! – cvk

+1

También usé django-filter y en combinación con el método get_queryset() anterior y funciona muy bien. fyi, filter.qs es el atributo que devuelve el queryset filtrado de un objeto filterset (parte de la aplicación django-filter) – rsp

+0

Para usar esta función para forms.DateField, ¿cómo puedo hacer? – Marcaum54

1

Tome un vistazo a django-filter que sea fácil solución para el filtrado de datos en vista

+0

parece prometedor, ¡pero echa de menos AJAX! – andi

Cuestiones relacionadas