Search code examples
pythondjangofilterdjango-filterchoicefield

django-filter: Using ChoiceFilter with choices dependent on request


I am using django-filter and need to add a ChoiceFilter with choices dependent on the request that I receive. I am reading the docs for ChoiceFilter but it says: This filter matches values in its choices argument. The choices must be explicitly passed when the filter is declared on the FilterSet.

So is there any way to get request-dependent choices in the ChoiceFilter?

I haven't actually written the code but the following is what I want -

class F(FilterSet):
    status = ChoiceFilter(choices=?) #choices depend on request
    class Meta:
        model = User
        fields = ['status']

Solution

  • I've been looking too hard that I found two different ways of doing it! (both by overriding the __init__ method). Code inspired from this question.

    class LayoutFilterView(filters.FilterSet):
        supplier = filters.ChoiceFilter(
            label=_('Supplier'), empty_label=_("All Suppliers"),)
    
        def __init__(self, *args, **kwargs):
            super(LayoutFilterView, self).__init__(*args, **kwargs)
    
            # First Method
            self.filters['supplier'].extra['choices'] = [
                (supplier.id, supplier.id) for supplier in ourSuppliers(request=self.request)
            ]
    
            # Second Method
            self.filters['supplier'].extra.update({
                'choices': [(supplier.id, supplier.name) for supplier in ourSuppliers(request=self.request)]
            })
    

    The function ourSuppliers is just to return a QuerySet to be used as choices

    def ourSuppliers(request=None):
        if request is None:
            return Supplier.objects.none()
    
        company = request.user.profile.company
        return Supplier.objects.filter(company=company)