Django 3.2智能分页get_elided_page_range方法初尝!

Django 3.2版本本月正式发布了, 其中一个重要变化就是新增了智能分页get_elided_page_range方法。Django 3.2之前的Paginator类将连续输出所有页码,非常不智能。本文将演示如何使用get_elided_page_range方法实现智能分页。

Django 3.2智能分页get_elided_page_range方法初尝!_第1张图片

get_elided_page_range方法解读

改方法接收3个参数,第一个参数number为当前页码数, on_each_side为当前页码左右两边的页数,on_ends为首尾页码范围。

Paginator.get_elided_page_range(number, on_each_side=3, on_ends=2)

如果当前页码为第10页,使用该方法将输出如下页码范围(page_range)。10左右两边各有3页,首尾各有2页,其余页码号码用...代替。将page_range这个变量传递到前端模板进行遍历即可实现智能分页。

[1, 2, '…', 7, 8, 9, 10, 11, 12, 13, '…', 49, 50]

Django 3.2之前版本非智能分页

我们有个House模型。为了模拟总页数非常多的情形,我们将每页记录数量设为1条。视图函数如下所示:

# Filter houses
def house_filter(request):
    qs = House.objects.all()
    paginator = Paginator(qs, 1) # 每页1条记录
    page = request.GET.get('page', 1) # 获取当前page页码,默认为1
    try:
        page_obj = paginator.page(page) # 分页
    except PageNotAnInteger:
        page_obj = paginator.page(1) 
    except EmptyPage:
        page_obj = paginator.page(paginator.num_pages)
    is_paginated = True if paginator.num_pages > 1 else False


    context = {'page_obj': page_obj, 'paginator': paginator,
               'is_paginated': is_paginated,}
    return render(request, 'house/house_index.html', context)


假如前端模板样式用bootstrap 4,对应分页的前端模板如下所示:

# house/house_index.html
{% block content %}
         
{% if page_obj %} {% for item in page_obj %} {% endfor %} {% endif %}
描述 小区 城市 房型 朝向 面积 价格(万元)
{ { item.description }} { { item.community }} { { item.community.get_city_display }} { { item.get_bedroom_display }} { { item.get_direction_display }} { { item.area }} { { item.price }}
{% if is_paginated %}
    {% if page_obj.has_previous %}
  • Previous
  • {% else %}
  • Previous
  • {% endif %}             # 注意下面这行   {% for i in page_obj.paginator.page_range %} {% if page_obj.number == i %}
  • { { i }} (current)
  • {% else %}
  • { { i }}
  • {% endif %} {% endfor %} {% if page_obj.has_next %}
  • Next
  • {% else %}
  • Next
  • {% endif %}
{% endif %}
{% endblock %}

分页效果如下所示,所有页码都展示了,非常的长,显然不是我们想要的。

Django 3.2智能分页get_elided_page_range方法初尝!_第2张图片

本例所使用House模型及完整样式代码见Django 3.0实战: 仿链家二手房信息查询网(附GitHub源码)。如果你还不知道如何在Django函数视图和基于类的视图中使用分页,请阅读下篇文章(点击原文阅读即可跳转)。

  • https://pythondjango.cn/django/basics/14-pagination/

现在我们就要对前面的视图和模板代码做出修改,实现智能分页。

Django 3.2智能分页

首先我们修改视图函数,使用get_elided_page_range方法获取智能分页范围(page_range), 并将这个变量传递给前端模板。

# Filter houses
def house_filter(request):
    qs = House.objects.all()
    paginator = Paginator(qs, 1) # 每页1条记录
    page = request.GET.get('page', 1) # 获取当前page页码,默认为1
    try:
        page_obj = paginator.page(page) # 分页
    except PageNotAnInteger:
        page_obj = paginator.page(1) 
    except EmptyPage:
        page_obj = paginator.page(paginator.num_pages)
    is_paginated = True if paginator.num_pages > 1 else False
    # 注意下面一行, 获取智能页码范围,并传递给模板
    page_range = paginator.get_elided_page_range(page, on_each_side=3, on_ends=2)
    context = {'page_obj': page_obj, 'paginator': paginator,
               'is_paginated': is_paginated, 'page_range': page_range }
    return render(request, 'house/house_index.html', context)

模板中我们只需要修改一行代码,如下所示:

{% block content %}
         
        {% if page_obj %}                {% for item in page_obj %} {% endfor %} {% endif %}
描述 小区 城市 房型 朝向 面积 价格(万元)
{ { item.description }} { { item.community }} { { item.community.get_city_display }} { { item.get_bedroom_display }} { { item.get_direction_display }} { { item.area }} { { item.price }}
{% if is_paginated %}
    {% if page_obj.has_previous %}
  • Previous
  • {% else %}
  • Previous
  • {% endif %}             # 注意下面一行代码 {% for i in page_range %} {% if page_obj.number == i %}
  • { { i }} (current)
  • # 如果页码为...跳转到第一页 {% elif i == '…' %}
  • { { i }}
  • {% else %}
  • { { i }}
  • {% endif %} {% endfor %}              {% if page_obj.has_next %}
  • Next
  • {% else %}
  • Next
  • {% endif %}
            {% endif %}
{% endblock %}

如果你还没注意模板中代码的变化,请再观察一下:

# Django 3.2之前
 {% for i in page_obj.paginator.page_range %}
# Django 3.2之后
 {% for i in page_range %}

新的展示效果是不是帅多了?

Django 3.2智能分页get_elided_page_range方法初尝!_第3张图片

本例仅展示了如何在函数视图中使用智能分页。如果你希望在基于类的视图中也使用智能分页,你可以重写get_context_data方法向模板传递智能页码范围page_range即可。

大江狗

2021.4

相关阅读

Django 3.2正式发布! 主要变化抢先看!

Django 3.0实战: 仿链家二手房信息查询网(附GitHub源码)

Django代码分享: 可以重用的Bootstrap 4分页模板

你可能感兴趣的:(Django基础连载,Django,web,javascript,数据可视化,django,html)