Mažas
Mažas

Reputation: 397

django pass extra arguments to filterset_class

I am using django-filter. I have filter class:

class ProductFilter(django_filters.FilterSet):
    def __init__(self, attribute=None, *args, **kwargs):
        super(ProductFilter, self).__init__(*args, **kwargs)
        #do stuff with attribute

and my views:

from django_filters.views import FilterView
class ProductListView(FilterView):
        model = Product
        ....
        filterset_class = ProductFilter

How can i pass arguments to ProductFilter __init__ function? filterset_class = ProductFilter(attribute='width') doesn't work.

Upvotes: 1

Views: 3019

Answers (2)

piagetjonathan
piagetjonathan

Reputation: 1

I successfully passed kwargs using the code below. This approach is similar to Alasdair’s validated method but with the correct arguments for functions and, in my opinion, better code organization. Here’s the code:

# views.py
class YourView(FilterView):
    template_name = "your_template.html"
    filterset_class = YourViewFilter

    def get_filterset_kwargs(self, filterset_class):
        kwargs = super().get_filterset_kwargs(filterset_class)
        kwargs["data"] = self.request.data
        return kwargs

# filters.py
class YourViewFilter(FilterSet):
    class Meta:
        model = YourView
        fields = ["somefield"]

    def __init__(self, *args, **kwargs):
        self.data = kwargs.pop("session", None)
        super().__init__(*args, **kwargs)
        # do something with self.data

Upvotes: 0

Alasdair
Alasdair

Reputation: 308999

You could try overriding the get_filterset_kwargs method:

class ProductListView(FilterView):
    model = Product
    ...
    filterset_class = ProductFilter

    def get_filterset_kwargs(self, filterset_class)
        kwargs = super(ProductListView, self).get_filterset_kwargs(filterset_class)
        kwargs['attribute'] = 'width'
        return kwargs

In your FilterSet class, you can either pop the attribute from kwargs:

class ProductFilter(django_filters.FilterSet):
    def __init__(self, **kwargs):
        attribute = kwargs.pop['attribute']
        super(ProductFilter, self).__init__(**kwargs)

Or explicitly include it in the signature.

class ProductFilter(django_filters.FilterSet):
    def __init__(self, attribute=None, **kwargs):
        super(ProductFilter, self).__init__(**kwargs)

Upvotes: 4

Related Questions