使用 Django Listview 在过滤查询集中分页
Pagination in filtered queryset using Django Listview
我在尝试过滤查询集时在通用 ListView 中使用分页时遇到问题。过滤器工作正常,但问题是当尝试访问不是第一个页面时,出现错误:无效页面 (2):该页面不包含任何结果
如果我删除所有分页会怎样?你会推荐什么?
该模板的目标是在列表中显示日期过滤的销售以及客户过滤器
这是我的代码:
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
这是我的模板:
{% extends "panel.html" %}
{% load static %}
{% block panel-content %}
<div class="grid-x medium-10">
<h3 class="cell medium-12" style="text-align: center;">Ventas</h3>
<div class="cell medium-12">  </div>
<form class="cell medium-10" method="GET">{% csrf_token %}
<div class="input-group grid-x medium-12">
<div class="input-group cell medium-3 grid-x">
<label class="cell medium-12">Desde:</label>
<span class="input-group-label"><i class="fi-calendar"></i></span>
<input type="date" id="date1" name="date1" class="input-group-field" type="date">
</div>
   
<div class="input-group cell medium-3 grid-x">
<label class="cell medium-12">Hasta:</label>
<span class="input-group-label"><i class="fi-calendar"></i></span>
<input type="date" id="date2" name="date2" class="input-group-field" type="date">
</div>
<div class="cell medium-1"></div>
<div class="input-group cell medium-3 grid-x">
<label class="cell medium-12">Cliente:</label>
<span class="input-group-label"><i class="fi-torso"></i></span>
<select id="clientselect" name="clientselect" class="input-group-field">
<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 class="cell medium-1"></div>
<div class="cell medium-1">
<button type="submit" class="button cell medium-4"><i class="fi-filter"></i>  Filtrar</button>
</div>
</div>
</form>
<div class="cell medium-12"> </div>
<table class="cell medium-12">
<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 class="button-group">
<a href="#" class="button warning tiny" data-toggle="modalView{{sale.pk}}"><i class="fi-eye"></i></a>
</td>
</div>
</tr>
<div class="tiny reveal" 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 class="cell" style="text-align: center;">Detalle de Venta</h4>
</div>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<ul class="pagination cell medium-12">
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}" style="color: wheat;">«</a></li>
{% else %}
<li class="disabled"><span style="color: wheat;">«</span></li>
{% endif %} {% for i in paginator.page_range %} {% if page_obj.number == i %}
<li class="active">
<span style="color: wheat;">{{ i }} <span class="sr-only">(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 class="disabled"><span style="color: wheat;">»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
{% endblock panel-content %}
失败的原因是如果您单击下一页,则查询字符串的其余部分(搜索参数)不会传递给以下请求。
您可以对查询字符串的其余部分进行编码:
class ListSales(LoginRequiredMixin, ListView):
# …
def <strong>urencode_filter</strong>(self):
qd = self.request.GET.copy()
qd.pop(self.page_kwarg, None)
return qd.urencode()
在指向其他页面的链接中,然后添加 urlencode_filter()
值:
<li><a href="?page={{ page_obj.previous_page_number }}<strong>&{{ view.urlencode_filter }}</strong>" style="color: wheat;">«</a></li>
并使用指向上一页、下一页和任意页面的 所有 链接来执行此操作。
您还可以创建一个自定义 param_replace
模板标记来仅更新一个查询参数并保留所有其他参数:
<a href="?{% param_replace page=page_obj.previous_page_number %}">«</a>
详情见:https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/ and
我在尝试过滤查询集时在通用 ListView 中使用分页时遇到问题。过滤器工作正常,但问题是当尝试访问不是第一个页面时,出现错误:无效页面 (2):该页面不包含任何结果
如果我删除所有分页会怎样?你会推荐什么? 该模板的目标是在列表中显示日期过滤的销售以及客户过滤器
这是我的代码:
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
这是我的模板:
{% extends "panel.html" %}
{% load static %}
{% block panel-content %}
<div class="grid-x medium-10">
<h3 class="cell medium-12" style="text-align: center;">Ventas</h3>
<div class="cell medium-12">  </div>
<form class="cell medium-10" method="GET">{% csrf_token %}
<div class="input-group grid-x medium-12">
<div class="input-group cell medium-3 grid-x">
<label class="cell medium-12">Desde:</label>
<span class="input-group-label"><i class="fi-calendar"></i></span>
<input type="date" id="date1" name="date1" class="input-group-field" type="date">
</div>
   
<div class="input-group cell medium-3 grid-x">
<label class="cell medium-12">Hasta:</label>
<span class="input-group-label"><i class="fi-calendar"></i></span>
<input type="date" id="date2" name="date2" class="input-group-field" type="date">
</div>
<div class="cell medium-1"></div>
<div class="input-group cell medium-3 grid-x">
<label class="cell medium-12">Cliente:</label>
<span class="input-group-label"><i class="fi-torso"></i></span>
<select id="clientselect" name="clientselect" class="input-group-field">
<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 class="cell medium-1"></div>
<div class="cell medium-1">
<button type="submit" class="button cell medium-4"><i class="fi-filter"></i>  Filtrar</button>
</div>
</div>
</form>
<div class="cell medium-12"> </div>
<table class="cell medium-12">
<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 class="button-group">
<a href="#" class="button warning tiny" data-toggle="modalView{{sale.pk}}"><i class="fi-eye"></i></a>
</td>
</div>
</tr>
<div class="tiny reveal" 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 class="cell" style="text-align: center;">Detalle de Venta</h4>
</div>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<ul class="pagination cell medium-12">
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}" style="color: wheat;">«</a></li>
{% else %}
<li class="disabled"><span style="color: wheat;">«</span></li>
{% endif %} {% for i in paginator.page_range %} {% if page_obj.number == i %}
<li class="active">
<span style="color: wheat;">{{ i }} <span class="sr-only">(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 class="disabled"><span style="color: wheat;">»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
{% endblock panel-content %}
失败的原因是如果您单击下一页,则查询字符串的其余部分(搜索参数)不会传递给以下请求。
您可以对查询字符串的其余部分进行编码:
class ListSales(LoginRequiredMixin, ListView):
# …
def <strong>urencode_filter</strong>(self):
qd = self.request.GET.copy()
qd.pop(self.page_kwarg, None)
return qd.urencode()
在指向其他页面的链接中,然后添加 urlencode_filter()
值:
<li><a href="?page={{ page_obj.previous_page_number }}<strong>&{{ view.urlencode_filter }}</strong>" style="color: wheat;">«</a></li>
并使用指向上一页、下一页和任意页面的 所有 链接来执行此操作。
您还可以创建一个自定义 param_replace
模板标记来仅更新一个查询参数并保留所有其他参数:
<a href="?{% param_replace page=page_obj.previous_page_number %}">«</a>
详情见:https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/ and