Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I fix pagination when there is a GET filter from the URL?

In the main product browse page (www.url.com/works), pagination works well (displays 10 items at a time) and the URL becomes www.url.com/works/?page=2

In the same view, the works can be filtered by category (i.e. www.url.com/works/?collection=Drawing). Since it using the same view, it is still paginating by 10, but if I click other pages, it loses the /?collection=Drawing and just goes back to being www.url.com/works/?page=2.

How do I combine them to be something like www.url.com/works/?collection=Drawing&page=2 ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Thank you!

views.py

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from url_filter.filtersets import ModelFilterSet
    
class ProductListView(ListView):
model = Product
template_name = "products/product_all.html"
paginate_by = 10

def get_queryset(self, *args, **kwargs):
    sold = ProductPurchase.objects.filter(
        refunded=False
    ).values_list('product_id')
    qs = super(ProductListView, self).get_queryset(**kwargs)
    qs = qs.filter(for_sale=True, test_check=False).exclude(id__in=sold).order_by('-timestamp')

    categoryfilter = self.request.GET.get("collection")
    if categoryfilter:
        qs = qs.filter(
            Q(category__name__icontains=categoryfilter)
        )

    query = self.request.GET.get("q")
    if query:
        tags = Tag.objects.filter(
            slug=query
        ).values_list('products')
        qs = qs.filter(
            Q(title__icontains=query) |
            Q(description__icontains=query) |
            Q(material__icontains=query) |
            Q(id__in=tags)
        ).order_by("title")

    return MyFilterSet(data=self.request.GET, queryset=qs).filter()

product_all.html

<section class="mt-5">
  <div class="container">
            
      <div class="row mx-1 mb-5">
          <div class="py-0 my-0">
            <span class="hero-heading px-2 mr-2 text-sm"><a href="{% url 'products:list' %}">All</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Painting">Painting</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Drawing">Drawing</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Print">Print</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Sculpture">Sculpture/ Installation</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Textiles">Textiles</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Photography">Photography</a></span>
            <span class="hero-heading px-2 mr-2 text-sm"><a href="?collection=Mixed media">Mixed media</a></span>
          </div>
      </div>


            <div class="row">

              <!-- Grid -->
              <div class="products-grid col-xl-12 col-lg-8 order-lg-2">
                
                <div class="card-columns product-columns">
                  {% include "products/product_list_snippet.html" with object_list=products %}
                  
                </div>
                

                <nav aria-label="page navigation" class="d-flex justify-content-center mb-5 mt-3">
                  <ul class="pagination">
                    {% if page_obj.has_previous %}
                    <li class="page-item"><a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous" class="page-link"><span aria-hidden="true">Prev</span><span class="sr-only">Previous</span></a></li>
                    {% endif %}

                    {% for i in paginator.page_range %}
                      {% if page_obj.number == i %}
                    <li class="page-item active"><a href="#" class="page-link">{{ i }}</a></li>
                      {% else %}
                    <li class="page-item"><a href="?page={{ i }}" class="page-link">{{ i }}</a></li>
                      {% endif %}
                    {% endfor %}

                    {% if page_obj.has_next %}
                    <li class="page-item"><a href="?page={{ page_obj.next_page_number }}" aria-label="Next" class="page-link"><span aria-hidden="true">Next</span><span class="sr-only">Next     </span></a></li>
                    
                    {% endif %}
                  </ul>
                </nav>
              </div>

      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
      <script type="text/javascript">
      jQuery(document).ready(function() {
        
        var btn = $('#button');

        $(window).scroll(function() {
          if ($(window).scrollTop() > 300) {
            btn.addClass('show');
          } else {
            btn.removeClass('show');
          }
        });

        btn.on('click', function(e) {
          e.preventDefault();
          $('html, body').animate({scrollTop:0}, '1000');
        });

      });

      </script>


      </div>
      </div>

>Solution :

You can add a method to the view to obtain an URL-encoded queryset of all items except the page with:

class ProductListView(ListView):
    # …

    def querystring_url(self):
        data = self.request.GET.copy()
        data.pop(self.page_kwarg, None)
        return data.urlencode()

Then in the template you can write a link to a page, for example with:

<a href="?page={{ page_obj.previous_page_number }}&amp;{{ view.querystring_url }}">…</a>

You should update all the links with a different page such that these make use of the querystring_url of the view.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading