Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check and clear filters with django-filter

I am using django-filter to filter a ListView and would like to display a "Clear all filters" link if any filters are applied.

Due to the generic nature of the filtering system I haven't yet found a straightforward way to achieve this.

The only thing I came up with so far is to return the regular queryset in the get_queryset method of the view if a "clear" flag is present in the request, however this doesn't actually clear the filters - it just returns all the data.

Does anyone have a solution/idea for this?

Update: Solution

After Jerin's comment I decided to solve this problem in 2 separate parts:

has filter:

I check if any of the fields I defined in my filter class are in the request. My solution looks a bit different as I'm using class based views so I abstracted it away in a mixin but if you're using simple views like here, you could just do:

def product_list(request):
    f = ProductFilter(request.GET, queryset=Product.objects.all())
    has_filter = any(field in request.GET for field in 
set(f.get_fields()))

    return render(request, 'my_app/template.html', {
        'filter': f,
        'has_filter': has_filter
    })

clear all filters:

A simple redirect to your list view:

{% if has_filter %}
  <a href="{%  url 'products' %}">{% trans 'Clear all filters' %}</a>
{% endif %}
like image 772
Christof Avatar asked Mar 07 '23 11:03

Christof


1 Answers

Here is the mixup version of the answer (combination of mine and Chris)

You could place a Clear all filters button and that will redirect to your default ListView (/host/end/point/). But some non-filter parameters (such as pagination or something else) may occur in URL. So the better option is, check for any filter fields in URL and if so, display the filter clearing link

The opted solution is,

def product_list(request):
    f = ProductFilter(request.GET, queryset=Product.objects.all())
    has_filter = any(field in request.GET for field in set(f.get_fields()))

    return render(request, 'my_app/template.html', {
        'filter': f,
        'has_filter': has_filter
    })


and in template,

{% if has_filter %}
  <a href="{%  url 'products' %}">{% trans 'Clear all filters' %}</a>
{% endif %}
like image 102
JPG Avatar answered Mar 28 '23 07:03

JPG