2014-11-30 9 views
8

Ho un sacco di risorse e voglio applicare DjangoFilterBackend a tutti loro.Come applicare un back-end del filtro a tutti i campi di tutte le risorse in Django Rest Framework?

provato a installare in settings.py

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

Ma non ha funzionato

Ho provato ad aggiungere solo filter_backends = (filters.DjangoFilterBackend,) ad una delle mie risorse e ancora non ha funzionato.

Solo dopo aver aggiunto esplicitamente filter_fields = ('col1','col2',) ha iniziato a funzionare solo con quei campi.

Esiste un modo per applicare il back-end del filtro a tutte le risorse e tutti i campi (analogamente alle autorizzazioni, ad esempio ...)?

Grazie.

+0

Hai installato l'applicazione django-filter? – mariodev

+2

sì. Come ho scritto - Funziona quando imposto filtribackback e campi in modo esplicito. – haki

risposta

10

In questo momento stai dicendo a Django REST Framework di utilizzare DjangoFilterBackend per tutte le visualizzazioni, ma non stai dicendo come dovrebbe essere generato il FilterSet.


django-filter genererà automaticamente un FilterSet per tutti i campi su un modello se il fields are set to None. Django REST Framework genererà automaticamente unse filter_fields are not set to None, il che significa che non sarà possibile utilizzare il valore predefinito DjangoFilterBackend.

È tuttavia possibile creare un numero personalizzato DjangoFilterBackend, che genererà automaticamente lo FilterSet per tutti i campi sul modello.

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 

Questa utilizzerà ancora il back-end filtro originale per situazioni in cui la vista definisce un costume filter_class o filter_fields, ma genera un personalizzato FilterSet per tutte le altre situazioni. Tieni presente che non devi consentire che i campi che non vengono restituiti tramite l'API vengano filtrati, in quanto ti stai aprendo a futuri problemi di sicurezza (come ad esempio le persone che filtrano un elenco utenti tramite password).

+0

Hey @Kevin Brows, sembra un'ottima soluzione ma mi richiede ancora di impostare 'filter_backend' per ogni risorsa (ho cambiato il backend predefinito nelle impostazioni in' app.filters.AllDjangoFilterBackend' e non funziona ancora. dopo aver impostato esplicitamente il backend ha funzionato ...) in ogni modo anche intorno a questo? – haki

+0

Se si sostituisce manualmente filter_backend sulla vista, sarà necessario ripeterlo di nuovo. Se è possibile, rimuovilo dalla classe –

+0

per favore spiegami come sovrascrivere filter_backend sulla vista ...... – amrit

Problemi correlati