Search code examples
djangodjango-rest-frameworkdjango-filterdjango-filters

How to allow generic filtering with djangorestframework on all fields?


My packages:

  • djangorestframework==3.2.5
  • django-filter==0.11.0
  • djangorestframework-filters==0.5.0

I'm using djangorestframework to expose my models as a restful api. To make my and the frontend dev's life easier I want to allow any filter lookup on any model field. But as far as I could see neither of the packages supports such generic filtering out of the box. I can use a AllLookupsFilter but still need to create a filterset class per model and specify each field.

Is there a generic approach to allow filtering on all models and all fields?


Solution

  • I created a little helper function that creates the filterset on-the-fly based on the queryset model of the modelviewset. It adds an AllLookupFilter for each field in the model.

    from rest_framework import viewsets
    import rest_framework_filters as filters
    
    
    def create_universal_filter(klass):
        """Creates filterset class with all lookups  for all fields of given class"""
        field_filters = dict((f, filters.ALL_LOOKUPS) 
                        for f in klass._meta.get_all_field_names())
    
        class MyFilter(filters.FilterSet):
            class Meta:
                model = klass
                fields = field_filters
        return MyFilter
    
    
    class GenericFilterModelViewSet(viewsets.ModelViewSet):
        """Allows all lookups on all fields"""
        def __init__(self, *args, **kwargs):
            self.filter_class = create_universal_filter(self.queryset.model)
    

    Then I let the modelviewsets where I want to allow generic filtering inherit from it:

    class DerivateGroupViewSet(GenericFilterModelViewSet):
        queryset = models.DerivateGroup.objects.all()
        serializer_class = serializers.DerivateGroupSerializer