2014-11-30 6 views
8

Mam dużo zasobów i chcę zastosować DjangoFilterBackend do wszystkich z nich.Jak zastosować filtrowanie do wszystkich pól wszystkich zasobów w Django Rest Framework?

próbowano ustawienie w settings.py

'DEFAULT_FILTER_BACKENDS': [ 
      'rest_framework.filters.DjangoFilterBackend', 
     ] 

Ale to nie działa

Próbowałem dodając tylko filter_backends = (filters.DjangoFilterBackend,) do jednego z moich zasobów i nadal nie działa.

Dopiero po wyraźnym dodaniu filter_fields = ('col1','col2',) zaczęto pracować tylko z tymi polami.

Czy istnieje sposób, w jaki mogę zastosować filtr do wszystkich zasobów i wszystkich pól (w ten sam sposób, w jaki mam uprawnienia, na przykład ...)?

Dzięki.

+0

Czy zainstalowałeś aplikację Django-Filter? – mariodev

+2

tak. Tak jak napisałem - działa, gdy jawnie ustawiam filterbackend i pola. – haki

Odpowiedz

10

W tej chwili mówisz Django REST Framework, aby używał DjangoFilterBackend dla wszystkich widoków, ale nie mówisz, jak powinno być wygenerowane FilterSet.


django-filter automatycznie wygeneruje FilterSet dla wszystkich pól na model z fields are set to None. Django REST Framework automatycznie wygeneruje FilterSet, jeśli filter_fields are not set to None, co oznacza, że ​​nie będzie można użyć domyślnego DjangoFilterBackend.

Można jednak utworzyć niestandardową DjangoFilterBackend, która automatycznie wygeneruje FilterSet dla wszystkich pól w modelu.

from rest_framework.filters import DjangoFilterBackend 

class AllDjangoFilterBackend(DjangoFilterBackend): 
    """ 
    A filter backend that uses django-filter. 
    """ 

    def get_filter_class(self, view, queryset=None): 
     """ 
     Return the django-filters `FilterSet` used to filter the queryset. 
     """ 
     filter_class = getattr(view, 'filter_class', None) 
     filter_fields = getattr(view, 'filter_fields', None) 

     if filter_class or filter_fields: 
      return super(AllDjangoFilterBackend, self).get_filter_class(self, view, queryset) 

     class AutoFilterSet(self.default_filter_set): 
      class Meta: 
       model = queryset.model 
       fields = None 

     return AutoFilterSet 

ten będzie nadal korzystać z oryginalnego backend filtra dla sytuacji, w których widok definiuje zwyczaj filter_class lub filter_fields, ale będzie generować niestandardową FilterSet dla wszystkich innych sytuacjach. Pamiętaj, że nie należy zezwalać na filtrowanie pól, które nie są zwracane przez interfejs API, ponieważ otwierasz się na przyszłe problemy z bezpieczeństwem (np. Przez filtrowanie listy użytkowników za pomocą haseł).

+0

Hej @ Kevin Brows, To wygląda na świetne rozwiązanie, ale nadal wymaga ustawienia "filtru" dla każdego zasobu (zmieniłem domyślny backend w ustawieniach na 'app.filters.AllDjangoFilterBackend' i nadal nie działa. po ustawieniu backendu jawnie zadziałało ...) w jakiś sposób? – haki

+0

Jeśli ręcznie zastąpisz filter_backend w widoku, będziesz musiał powtórzyć go ponownie. Jeśli możesz, usuń to z klasy –

+0

, możesz wyjaśnić, jak zastąpić filter_backend w widoku ...... – amrit

Powiązane problemy