First time using django-filter, so I might be using it wrong.
I'm basically trying to mimic Django Admin filtering, using a generic FilterView, setting filterser_class and adding paginate_by
filters.py
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains', label='Filter by Title')
categories = django_filters.AllValuesFilter(
field_name='categories__name',
label="Filter by Category",
widget=django_filters.widgets.LinkWidget(attrs={'class': 'list-menu'}),
)
brand = django_filters.AllValuesFilter(
field_name='brand__short_name',
label="Filter by Brand",
widget=django_filters.widgets.LinkWidget(attrs={'class': 'list-menu'}),
)
class Meta:
model = Product
fields = ['categories', 'brand', 'name']
views.py
class ProductFilterView(FilterView):
filterset_class = ProductFilter
paginate_by = 20
product_filter.html
<section class="section-content padding-y">
<div class="container">
<div class="row">
<aside class="col-md-3">
<div class="card">
<form method="get">
{% csrf_token %}
{% for field in filter.form.visible_fields %}
<article class="filter-group">
<header class="card-header">
<a href="#" data-toggle="collapse" data-target="#collapse_1" aria-expanded="true" class="">
<i class="icon-control fa fa-chevron-down"></i>
<h6 class="title">{{ field.label_tag }}</h6>
</a>
</header>
<div class="filter-content collapse show" id="collapse_1">
<div class="card-body">
{{ field }}
</div> <!-- card-body.// -->
</div>
</article> <!-- filter-group .// -->
{% endfor %}
<input type="submit" class="btn btn-block btn-primary" value="Filter"/>
</form>
</div> <!-- card.// -->
</aside> <!-- col.// -->
<main class="col-md-9">
<header class="border-bottom mb-4 pb-3">
<div class="form-inline">
<span class="mr-md-auto">{{ filter.qs | length }} products found </span>
</div>
</header><!-- sect-heading -->
<div class="row">
{% for obj in page_obj %}
<div class="col-md-4">
<figure class="card card-product-grid">
<div class="img-wrap">
<img src="/media/{{ obj.productimage_set.first.image|default:'products/missing.png' }}">
</div> <!-- img-wrap.// -->
<figcaption class="info-wrap">
<div class="fix-height">
<a href="./product-detail.html" class="title">{{ obj.name }}</a>
<div class="price-wrap mt-2">
<span class="price">$ {{ obj.price }}</span>
<!--<del class="price-old">$1980</del>-->
</div>
</div>
<a href="#" class="btn btn-block btn-primary">Add to cart</a>
</figcaption>
</figure>
</div> <!-- col.// -->
{% endfor %}
</div> <!-- row end.// -->
<nav class="mt-4" aria-label="Page navigation">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="?page=1">First</a></li>
<li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">First</a></li>
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
{% endif %}
{% for page in page_obj.paginator.page_range %}
{% ifequal page page_obj.number %}
<li class="page-item active"><a class="page-link">{{ page }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ page }}">{{ page }}</a></li>
{% endifequal %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a></li>
<li class="page-item"><a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Next</a></li>
<li class="page-item disabled"><a class="page-link" href="#">Last</a></li>
{% endif %}
</ul>
</nav>
</main> <!-- col.// -->
</div>
</div> <!-- container .// -->
</section>
It almost works as intended.
But those pagination urls will reset any filtering.
I'm considering using {{ request.GET.param1 }} to rebuild all the filters, but it doesn't feel like the right way to solve this.
I've tried a solution using context processors, as described by José L. Patiño here:
How to paginate Django with other get variables?
But it leads to another problem: it's possible to reapply filtering after advancing some pages, and it results in invalid pages.
Any suggestions?