Django项目中分页的使用,以及条件检索后点击下一页查询条件丢失情况的解决方案
后台代码
因为有其他功能也需要分页,我就封装了一个page_goods分页的方法,其他功能可以直接调用
# 分页
def page_goods(request, goods):
'''
:param request: request对象
:param goods: 传入的全部商品(例如:goods = Goods.objects.all())
:return: context(字典:包含分页后的商品,以及页码数)
'''
context = {}
paginator = Paginator(goods, 5)
page = request.GET.get('page', 1)
# 非法数值则返回1 数值为空页返回1
goods_list = paginator.get_page(page)
# 使用了列表生成式,这样可以避免超出页码范围或出现页码数为负数的情况
page_list = [x for x in range(goods_list.number - 2, goods_list.number + 3) if x in paginator.page_range]
# 添加省略号
if page_list[0] - 1 >= 2: # 判断当前第一个元素减1是否大于2
page_list.insert(0, "...") # 则插入该数组成为第一个元素 ...
if paginator.num_pages - page_list[-1] >= 2: # 判断最大页码数和最后一个元素相减是否大于2
page_list.append("...") # 则添加一个元素
# 添加首尾页
if page_list[0] == "...":
page_list.insert(0, 1) # 则插入该数组成为第一个元素(首页)
if page_list[-1] != paginator.num_pages: # 判断是否不等于最大页码
page_list.append(paginator.num_pages) # 不等于则插入到最后一个元素(尾页)
context['goods_list'] = goods_list
context['page_list'] = page_list
return context
前台html代码(样式基于Boostrap)
<div class="box-footer" align="right" id="page">
<ul class="pagination-wrap">
<li class="pagenum pagination-btn">
{% if goods_list.has_previous %}
<a style="display: block" href="?price_from={{ price_from }}&price_to={{ price_to }}&upload_date_from={{ upload_date_from|date:"Y-m-d" }}&upload_date_to={{ upload_date_to|date:"Y-m-d" }}&page={{ goods_list.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
{% else %}
<span class="pagination-disabled" aria-hidden="true">«</span>
{% endif%}
</li>
{% for page_list in page_list %}
{% if page_list == goods_list.number %}
<li class="pagenum pagination-btn pagination-current"><span>{{ page_list }}</span></li>
{% else %}
{% if page_list == '...' %}
<li class="pagenum pagination-btn"><span>{{ page_list }}</span></li>
{% else %}
<li class="pagenum pagination-btn"><a style="display: block" href="?price_from={{ price_from }}&price_to={{ price_to }}&upload_date_from={{ upload_date_from|date:"Y-m-d" }}&upload_date_to={{ upload_date_to|date:"Y-m-d" }}&page={{ page_list }}">{{ page_list }}</a></li>
{% endif %}
{% endif %}
{% endfor %}
<li class="pagenum pagination-btn">
{% if goods_list.has_next %}
<a style="display: block" href="?price_from={{ price_from }}&price_to={{ price_to }}&upload_date_from={{ upload_date_from|date:"Y-m-d" }}&upload_date_to={{ upload_date_to|date:"Y-m-d" }}&page={{ goods_list.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
{% else %}
<span class="pagination-disabled" aria-hidden="true">»</span>
{% endif %}
</li>
</ul>
</div>
效果图
开发中遇到的问题及解决方案
问题描述:该项目是基于电商的一款项目,商品列表的上方是条件检索区域,刚开始的时候输入条件得到检索结果后,商品列表会出现检索后的结果商品,这个时候如果点击下一页跳转的不是当前搜索结果的下一页而是未检索全部商品的下一页,最后找出问题所在,跳转页码的时候需要把搜索条件拼接到跳转页码的href上,也就是上方html代码块中
href="?price_from={{ price_from }}&price_to={{ price_to }}&upload_date_from={{ upload_date_from|date:"Y-m-d" }}&upload_date_to={{ upload_date_to|date:"Y-m-d" }}&page={{ goods_list.previous_page_number }}"
,
这里边{{}}是后台返回的条件变量:比如seller_volume_from=request.GET.get('seller_volume_from')
,
查资料时看到别人有用js写的,效果是一样的,我觉得这种更方便,也灵活运用了Django后台返回过来的变量。拼接href时也有其他的方法,目的都一样,希望可以帮到大家,谢谢~