Assuming I have a queryset and some filters I got from the front end, can I use the pre-defined FilterSet to filter over the queryset? example:
models.py
class User(models.Model):
name = models.CharField(...)
score = models.IntegerField(...)
filters.py
class UserFilter(django_filters.FilterSet):
q = django_filters.CharFilter(method="text_search_filter")
score_min = django_filters.NumberFilter(field_name="score", lookup_expr="gte")
score_max = django_filters.NumberFilter(field_name="score", lookup_expr="lte")
class Meta:
model = User
fields = {}
def text_search_filter(self, queryset, name, value):
return queryset.filter(name__icontains=value)
views.py
class UserView(View):
filter_class = UserFilter
...
def post(self, request, **kwargs):
qs = User.object.all()
filters = {"q": "john doe", "score_min": 5, "score_max": 10}
Can I call UserFilter and pass the filter dict? To prevent me applying those filters again, since I already have those defined in the UserFilter
Here's what I tried and didn't work:
views.py
def post(self, request, **kwargs):
qs = User.object.all()
filters = {"q": "john doe", "score_min": 5, "score_max": 10}
filter = UserFilter(request.GET, queryset=qs)
filter.is_valid()
qs = filter.filter_queryset(qs) # Did not apply the filters
Here's what worked for me:
the method filter_queryset
uses form.cleaned_data
as the filter paramaters. When I called it it was not initialised, therefor no filters were applied.
I used the source code to create my own function that receives the filter params.
def filter_queryset(filter_params, filterset, queryset):
filters = filterset.filters
for param, value in filter_params.items():
... # you might want to serialize some fields, like date (which is otherwise done under the hood to cleaned_data)
queryset = filters[param].filter(queryset, value)
return queryset.distinct()