2011-08-10 11 views
12

Używam ogólnego widoku opartego na klasie Django 1.3, aby wyświetlić listę obrazów, ale chcę dodać filtr, który umożliwia użytkownikowi zawężenie wyświetlanych wyników.Jak utworzyć formularz filtrujący dla ogólnej listy obiektów w klasie w Django?

Moje obecne prace podejście, ale czuje się dość hackish:

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 

Czy istnieją lepsze sposoby, aby dodać niestandardowe filtrowanie do ogólnego widoku?

Odpowiedz

20

używam samo podejście, ale ogólne, używając 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 

ten pozwala określić listę akceptowanych filtrów, a oni nie muszą odpowiadać faktycznym .filter() słów kluczowych. Następnie można go rozwinąć w celu wsparcia bardziej złożone filtrowanie (rozdzielić przecinkiem, gdy robi __in lub __range filtr jest łatwym przykład)

+1

Właśnie okazało się, że Aplikacja [django-filter] (https://github.com/alex/django-filter) i połączyła ją z Twoim mixinem. Myślę, że to dla mnie wystarczająco czyste ;-) Dzięki! – cvk

+1

Użyłem również django-filter i w połączeniu z metą get_queryset() powyżej i to działa ładnie. fyi, filter.qs to atrybut, który zwraca przefiltrowany zestaw zapytań z obiektu zestawu filtrującego (część aplikacji filtrującej django). – rsp

+0

Aby użyć tej funkcji w formularzach .DateField, jak mogę to zrobić? – Marcaum54

1

Spójrz na django-filter to proste rozwiązanie do filtrowania danych w widoku

+0

wygląda obiecująco, jednak nie trafia w AJAX! – andi

Powiązane problemy