In Django Rest Framework want to pass a kwarg
to my ClubFilter
class from within my view.
class ClubView(ListCreateView):
queryset = Club.objects.all()
serializer_class = ClubSerializer
filter_backends = (DjangoFilterBackend,)
filter_class = ClubFilter
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
So I tried added self.filter_class = ClubFilter(**kwargs)
to the list methoud but I get the error:
'ClubFilter' object is not callable
How can I pass in kwarg to my filter from the view?
filter_class
must be an class, it can't be class instance. So you must pass that variable when filter object is created.
Creating of filter object is done in filter backend, so you should subclass your filter backend and provide in it some method that can take your kwargs.
Im assuming that you're using DjangoFilterBackend
. You can then subclass it like this:
class MyFilterBackend(DjangoFilterBackend):
def filter_queryset(self, request, queryset, view):
filter_class = self.get_filter_class(view, queryset)o
if filter_class:
if hasattr(view, 'get_filter_kwargs'):
filter_kwargs = view.get_filter_kwargs(queryset=queryset)
else:
filter_kwargs = {'queryset': queryset}
return filter_class(request.query_params, **filter_kwargs).qs
return None
That will allow you to create method get_filter_kwargs
inside your view, that should return all kwargs that shuld be passed into your filter class. Remember to pass also queryset that is provided in kwarg for that method.
You can create custom filter backend
filters.py
class MyFilterBackend(DjangoFilterBackend):
def filter_queryset(self, request, queryset, view):
filter_class = self.get_filter_class(view, queryset)
if filter_class:
return filter_class(request.query_params, queryset=queryset, **kwargs).qs
return queryset
and use it instead DjangoFilterBackend