There is another way of doing this, and do it in a clean and professional way, which will save you the trouble of using Django Filters:
Create a helper function called clean_filters (This will help you clean filters that come in from the brownser:
def clean_filters(filters):
filters = {k: v for k, v in filters.items() if v}
return filters
Create another help function called search (this will help you get the parameters from the GET request and put them in a **filters inside the django filter directive. And return them back with the paginator so you can keep the same filters when moving from page to page):
from 'your_utils_file' import clean_filters
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def search(request):
filters = {
"account__first_name__icontains": request.GET.get("fname_kw"), # put your filters here
"account__last_name__icontains": request.GET.get("lname_kw"), # put your filters here
}
html_queries = {
"fname_kw": request.GET.get("fname_kw"),
"lname_kw": request.GET.get("lname_kw"),
}
filters = clean_filters(filters)
html_queries = clean_filters(html_queries)
posts = Post.objects.filter(**filters) # put your model here
page = request.GET.get('page', 1)
paginator = Paginator(posts, 8)
try:
posts= paginator.page(page)
except PageNotAnInteger:
posts= paginator.page(1)
except EmptyPage:
posts= paginator.page(paginator.num_pages)
return posts
Here is your view (this simply calls the search function to reduce the code of your view and make it easy for your code to maintain):
def search_page(request):
posts = search(request)
if posts is not None:
context = {
'posts': posts,
}
return render(request, "core/index.html", context)
return redirect("index")
Here is your HTML (just a classic pagination code for Django and Bootstrap. This also has the filter and the value of the filter in a loop inside the GET request):
<div class="mb-5">
{% if posts.has_other_pages %}
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
{% if posts.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ posts.previous_page_number }}{% for fil, fil_value in filters.items %}&{{fil}}={{fil_value}}{% endfor %}" tabindex="-1">
<i class="fa fa-angle-left"></i>
<span class="sr-only">Prev</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="javascript:void(0)" tabindex="-1">
<i class="fa fa-angle-left"></i>
<span class="sr-only">Prev</span>
</a>
</li>
{% endif %}
{% for i in posts.paginator.page_range %}
{% if posts.number == i %}
<li class="page-item active"><a class="page-link" href="javascript:void(0)">{{ i }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ i }}{% for fil, fil_value in filters.items %}&{{fil}}={{fil_value}}{% endfor %}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if posts.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ posts.next_page_number }}{% for fil, fil_value in filters.items %}&{{fil}}={{fil_value}}{% endfor %}">
<i class="fa fa-angle-right"></i>
<span class="sr-only">Next</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="javascript:void(0)">
<i class="fa fa-angle-right"></i>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}