I've implemented a custom method (or really overrid an existing method) that accomplishes what your trying to do without using django-filter.
One caveat is that here we use a ModelViewSet - so not entirely sure how this translates to a ListView. Otherwise, we will override override the get_queryset method of our ModelViewSet:
views.py
def BaseAPIView(...):
''' base view for other views to inherit '''
def get_queryset(self):
queryset = self.queryset
# get filter request from client:
filter_string = self.request.query_params.get('filter')
# apply filters if they are passed in:
if filters:
filter_dictionary = json.loads(filter_string)
queryset = queryset.filter(**filter_dictionary)
return queryset
The request url will now look like, for example: my_website.com/api/persons?filter={"social_media__Tiktok":true}
Or more precisely: my_website.com/api/persons?filter=%7B%social_media__Tiktok%22:true%7D
Which can be built like:
script.js
// using ajax as an example:
var filter = JSON.stringify({
"social_media__Tiktok" : true
});
$.ajax({
"url" : "my_website.com/api/persons?filter=" + filter,
"type" : "GET",
...
});
Some advantages:
- no need to specify which fields can be filtered on each view class
- write it once, use it everywhere
- front end filtering looks exactly like django filtering
- can do the same with
exclude
Some disadvantages:
- potential security risks if you want some fields to be non-filterable
- less intuitive front-end code to query a table
Overall, this approach has been far more useful for me than any packages out there.