Reputation: 941
I have following structure:
{
"some_data": 123,
"social_media": {
"Tiktok": "true",
"Instagram": "true"
}
}
with given list view
class PersonListView(generics.ListAPIView):
serializer_class = AllPersonSerializer
permission_class = permissions.IsAuthenticatedOrReadOnly
filter_backends = (DjangoFilterBackend, SearchFilter)
search_fields = ['name']
filterset_fields = {
'some_data': ['exact']
}
That i basically want to do is filter my result based on json value, something like mydomain/persons/all?social_media__Tiktok=true
Does DjangoFilterBackend allows it from the box or i should implement kinda custom method?
Upvotes: 2
Views: 948
Reputation: 516
You can write you, filter class, for filter social_media__Tiktok
and name
like this way. Hope this will help you to solve your problem.
import django_filters.rest_framework
import django_filters.filters
class FilterClass(django_filters.rest_framework.FilterSet):
filtename = filters.CharFilter(method="my_custom_filter", label="Title of filtername")
class Meta:
model = ModelName
fields = ("filtename",'name')
def my_custom_filter(self, queryset, name, value):
return ModelName.objects.filter(
Q(social_media__Tiktok=value)
)
class PersonListView(ListAPIView):
permission_classes = permission
serializer_class = serializers
filterset_class = FilterClass
Upvotes: 0
Reputation: 3527
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:
exclude
Some disadvantages:
Overall, this approach has been far more useful for me than any packages out there.
Upvotes: 3