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 ?
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>
CodePudding user response:
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 }}&{{ 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.