I have to build endpoint that must allow to filter by multiple values. It must looks like this:
http://example.com/page?field=1&field=2&filed=3
Lets say that field
is an IntegField
of MyModel
. An I want to query by any value in this field
.
I want to execute such or similiar query + validate the list of query params
MyModel.objects.filter(field__in=[1,2,3])
django-filter(https://django-filter.readthedocs.io/en/stable/) library looks promising but in the documentation I have not found an easy way to do something so simple. How can I achieve this?
Validation is also imortant. I dont want to allow to execute query with such param field=yolo
So far I have ended up with code that does not support validation
import django_filters as df
from django.forms.widgets import SelectMultiple
class MyFilter(df.FilterSet):
id = df.Filter(required=False, field_name="id", widget=SelectMultiple(), lookup_expr="in")
class Meta:
model = MyModel
fields = ["id"]
Maybe not the most elegant way, but this is how I achieved the goal:
from django_filters.fields import BaseCSVField
from django_filters.widgets import QueryArrayWidget
class MyBaseCSVField(BaseCSVField):
base_widget_class = QueryArrayWidget
class MyBaseInFilter(df.BaseInFilter):
base_field_class = MyBaseCSVField
class NumberInFilter(MyBaseInFilter, df.NumberFilter):
pass
class MytFilter(df.FilterSet):
field = NumberInFilter()
class Meta:
modem = MyModel
fields = ("field", )
So the key here is the QueryArrayWidget
and from the docstrin:
1. Values can be provided as csv string: ?foo=bar,baz
2. Values can be provided as query array: ?foo[]=bar&foo[]=baz
3. Values can be provided as query array: ?foo=bar&foo=baz
Generally this library is not well documented in my honest opinion.