carltongibson / django-filter

A generic system for filtering Django QuerySets based on user selections

Home Page:https://django-filter.readthedocs.io/en/main/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using django-filter with class-based views

perlun opened this issue · comments

Hi,

The docs are pretty clear on how to use this library with traditional Django views:

def product_list(request):
    filter = ProductFilter(request.GET, queryset=Product.objects.all())
    return render(request, 'my_app/template.html', {'filter': filter})

However, we are not using function-based views in our application but class-based views. I have tried various approaches on trying to get this working but I really don't get it.

Here's my last attempt:

class CustomersView(LoginRequiredMixin):
    queryset = Customer.objects.all()

    filter = CustomerFilter(self.request, queryset=self.queryset)

Obviously, this can't work since filter = CustomerFilter(request, queryset=queryset) relies on things from self which isn't available when declaring properties like that... 🙂

I've also tried various approaches which involved overriding get_queryset, like this:

    def get_queryset(self):
        filter = CustomerFilter(self.request, queryset=self.queryset)
        return self.queryset.filter(filter)

But with this I'm getting an error cannot unpack non-iterable CustomerFilter object. There's probably something obvious I'm missing out here... please let me know what it is. 😄

Take a look at the bundled generic view implementation:

def get(self, request, *args, **kwargs):
filterset_class = self.get_filterset_class()
self.filterset = self.get_filterset(filterset_class)
if not self.filterset.is_bound or self.filterset.is_valid() or not self.get_strict():
self.object_list = self.filterset.qs
else:
self.object_list = self.filterset.queryset.none()
context = self.get_context_data(filter=self.filterset,
object_list=self.object_list)
return self.render_to_response(context)

It should give you the guidance you need.

In general you access the filtered QuerySet via filter.qs.