I´m having a problem when using pagination in generic ListView, when trying to filter queryset. The filter works fine, but the thing is when trying to access a page that isn´t the first,an error appears: Invalid page (2): That page contains no results
What if I remove all the pagination? What would you recommend? The goal of the template is to show date filtered sales in a list and also a client filter
This is my code:
class ListSales(LoginRequiredMixin, ListView):
template_name = "sales/list.html"
context_object_name = 'sales'
login_url = reverse_lazy('users_app:user-login')
paginate_by = 5
def get_queryset(self):
client = self.request.GET.get("clientselect", "")
date1 = self.request.GET.get("date1", '')
date2 = self.request.GET.get("date2", '')
if date1 == '':
date1 = datetime.date.today()
if date2 == '':
date2 = datetime.date.today()
queryset = Sale.objects.get_sales_list(date1, date2, client)
return queryset
And this my template:
{% extends "panel.html" %}
{% load static %}
{% block panel-content %}
<div >
<h3 style="text-align: center;">Ventas</h3>
<div >  </div>
<form method="GET">{% csrf_token %}
<div >
<div >
<label >Desde:</label>
<span ><i ></i></span>
<input type="date" id="date1" name="date1" type="date">
</div>
   
<div >
<label >Hasta:</label>
<span ><i ></i></span>
<input type="date" id="date2" name="date2" type="date">
</div>
<div ></div>
<div >
<label >Cliente:</label>
<span ><i ></i></span>
<select id="clientselect" name="clientselect" >
<option value="0" id="option0" name="option0" >Todos</option>
<option value="-1" id="option-1" name="option-1" >Sin Cliente</option>
{% for client in clients %}
<option value="{{client.pk}}" id="option{{client.pk}}" name="option{{client.pk}}" >{{client.full_name}}</option>
{% endfor %}
</select>
</div>
<div ></div>
<div >
<button type="submit" ><i ></i>  Filtrar</button>
</div>
</div>
</form>
<div > </div>
<table >
<thead>
<th>Fecha</th>
<th>Nro Factura</th>
<th>Cliente</a></th>
<th>Monto</th>
<th>Acciones</th>
</thead>
<tbody>
{% for sale in sales %}
<tr>
<td>{{ sale.show_date }}</td>
<td>{{ sale.invoice_number }}</td>
<td>{{ sale.client.full_name }}</td>
<td>${{ sale.amount_with_discount}}</td>
<td>
<div >
<a href="#" data-toggle="modalView{{sale.pk}}"><i ></i></a>
</td>
</div>
</tr>
<div id="modalView{{sale.pk}}" style="background-color:rgb(51,51,51);" data-reveal data-close-on-click="true" data-animation-in="spin-in" data-animation-out="spin-out">
<h4 style="text-align: center;">Detalle de Venta</h4>
</div>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<ul >
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}" style="color: wheat;">«</a></li>
{% else %}
<li ><span style="color: wheat;">«</span></li>
{% endif %} {% for i in paginator.page_range %} {% if page_obj.number == i %}
<li >
<span style="color: wheat;">{{ i }} <span >(actual)</span></span>
</li>
{% else %}
<li><a href="?page={{ i }}" style="color: wheat;">{{ i }}</a></li>
{% endif %} {% endfor %} {% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}" style="color: wheat;">»</a></li>
{% else %}
<li ><span style="color: wheat;">»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
{% endblock panel-content %}
CodePudding user response:
The reason this fails is because if you click on the next page, the rest of the querystring (the search parameters) are not passed to the following request.
You can encode the rest of the querystring with:
class ListSales(LoginRequiredMixin, ListView):
# …
def urencode_filter(self):
qd = self.request.GET.copy()
qd.pop(self.page_kwarg, None)
return qd.urencode()
In the links to the other pages, you then add the urlencode_filter() value with:
<li><a href="?page={{ page_obj.previous_page_number }}&{{ view.urlencode_filter }}" style="color: wheat;">«</a></li>
and do this with all links to previous, next, and arbitrary pages.
CodePudding user response:
You could also create a custom param_replace template tag to only update one query param and keep all others:
<a href="?{% param_replace page=page_obj.previous_page_number %}">«</a>
For details see: https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/ and https://stackoverflow.com/a/22735278/10987661
