[Answered ]-FIlter Class Based View ListView that has pagination

1👍

✅

You want filtering and pagination at the same time.

you need to make your pagination to keep your querystrings then you can have them at the same time. Because when you click on next page your querystring will be like this .../?page=page_number so your filtering will be gone.

you can do this:

  1. Inside your app directory create a folder called templatetags.

  2. Inside the templatetags folder create a file called pagination_tags.py(name is up to you).

    # Your template tag in app_name/templatetags/pagination_tags.py
    from django import template
    from urllib.parse import urlencode
    
    
    register = template.Library()
    
    @register.simple_tag
    def url_replace (request, field, value):
        dict_ = request.GET.copy()
        dict_[field] = value
    
        return dict_.urlencode()   
    
  3. After creating your template tag load it in your html page and use it.

    {% load pagination_tags %}
    
    {% if is_paginated %}
    <nav aria-label="Page navigation example" class="d-flex justify-content-center pt-3">
      <ul class="pagination">
        {% if page_obj.has_previous and page_obj.number != 2 %}
        <li class="page-item"><a class="page-link text-dark" href="?{% url_replace request 'page' 1 %}" tabindex="-1" aria-disabled="true">First Page</a></li>
        {% endif %}
        {% if page_obj.has_previous %}
        <li class="page-item"><a class="page-link text-dark" href="?{% url_replace request 'page' page_obj.previous_page_number %}">{{ page_obj.previous_page_number }}</a></li>
        {% endif %}
        <li class="page-item disabled"><a class="page-link" href="#">{{ page_obj.number }}</a></li>
        {% if page_obj.has_next %}
        <li class="page-item"><a class="page-link text-dark" href="?{% url_replace request 'page' page_obj.next_page_number %}">{{ page_obj.next_page_number }}</a></li>
        {% endif %}
        {% if page_obj.paginator.num_pages != page_obj.number and page_obj.paginator.num_pages != page_obj.next_page_number %}
        <li class="page-item"><a class="page-link text-dark" href="?{% url_replace request 'page' page_obj.paginator.num_pages %}">Last Page</a></li>
        {% endif %}
      </ul>
    </nav>
    {% endif %}  
    
  4. And your ListView should be replaced by FilterView

    from django_filters.views import FilterView
    from .models import WoodhistAzolveInvoices
    from .filters import WoodhistAzolveInvoicesFilter
    
    
    class InvoicesListView(FilterView):
        model = WoodhistAzolveInvoices
        template_name = "home.html"
        filterset_class = WoodhistAzolveInvoicesFilter
        context_object_name = 'invoices'
        ordering = ['suppliername', 'invoicenumber']
        paginate_by = 50 
    

Leave a comment