Django框架(二十二:实现分页功能的几种方式)

本文详细介绍了在Django框架下实现分页功能的三种方法,包括简单的方法和一种利用Ajax实现的复杂方式,帮助开发者更好地管理网页内容展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍三种实现分页功能的方式,前两种为简单的,后一种稍微复杂一些
第一种方式:
如图所示,能一次将所有页都能展示出来
在这里插入图片描述
视图函数:

from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage, EmptyPage
def select(request):
    # 1. 把需要分页的数据全部查询出来;
    user_list = User.objects.all()
    # 2. 利用user_list数据,创建一个分页器对象
    # 参数1:要分页的数据;参数2:设置每页要展示的数据个数;参数3:如果最后一页不到5个数据,是否将最后一页的数据合并到上一页进行展示;默认是False,不合并;
    paginator = Paginator(user_list, 5)
    # 3. 创建页面对象Page,每一个page对应的是每一个页面,这个page中包含:
    # page对象有三个属性:
    # a> page.number: 表示当前查询的页码;
    # b> page.object_list: 表示当前页要展示的数据;
    # c> page.paginator: 它就是上面创建的Paginator(user_list, 5)这个对象,无论是哪一页,这个paginator对象始终跟着Page对象;
    try:
        page_number = request.GET.get('page', '1')
        page = paginator.page(page_number)
    except (PageNotAnInteger, EmptyPage, InvalidPage):
        # 如果出现上述异常,默认展示第1页
        page = paginator.page(1)

    return render(request, 'index.html', {'page': page})

模板中:

<nav aria-label="Page navigation">
        {% for data in page.object_list %}
            <p>{{ data.id }}-{{ data.name }}-{{ data.age }}</p>
        {% endfor %}
        <ul class="pagination">
            {% if page.has_previous %}
                {# page.has_previous: 判断当前页page是否含有上一页的属性 #}
                {# page.previous_page_number:上一页的页码 #}
                <li>
                    <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
                        <span aria-hidden="true">上一页</span>
                    </a>
                </li>
            {% endif %}
            {# 每次点击页码,这20次循环都会从头开始循环。 #}
            {% for page_number in page.paginator.page_range %}
                {% if page_number == page.number %}
                    {# 如果当前查询的页码和循环的页码刚好相等 #}
                    <li class="active"><a href="?page={{ page_number }}">{{ page_number }}</a></li>
                {% else %}
                    <li><a href="?page={{ page_number }}">{{ page_number }}</a></li>
                {% endif %}
            {% endfor %}
            {% if page.has_next %}
                <li>
                    <a href="?page={{ page.next_page_number }}" aria-label="Previous">
                        <span aria-hidden="true">下一页</span>
                    </a>
                </li>
            {% endif %}
      </ul>
    </nav>

第二种形式:
在这里插入图片描述
视图函数:

def process_paginator(request, article_list):
    paginator = Paginator(article_list, 1)
    try:
        page_number = int(request.GET.get('page', '1'))
        page = paginator.page(page_number)
    except (PageNotAnInteger, EmptyPage, InvalidPage):
        page = paginator.page(1)
    return page

模板中:
在这里插入图片描述

第三种方式:

在这里插入图片描述

视图函数:

def select(request):
    users = UserModel.objects.all()
    paginator = Paginator(users, 10)
    page_num = request.GET.get('page', '1')
    try:
        page = paginator.page(page_num)
    except(PageNotAnInteger, EmptyPage, InvalidPage):
        page = paginator.page('1')
    return render(request,'index.html',locals())

自定义一个标签:

from django import template
register = template.Library()



@register.simple_tag
def custom_paginator(page, num_total_pages=9, num_back_pages=3):
    '''
    page: 分页的页码对象;在views.py中创建的;
    num_total_pages:预定义整个分页器展示10个页码;
    num_back_pages:预定义,当前页码后面少于4个页码的时候,分页器开始滚动,最后无法滚动的除外。


    分页的情况:(默认展示10个分页按钮,并且保证当前点击的页码后面至少是4个页码)
    总页数如果没有超过10页,则页码全部展示,且没有滚动符...
    总页数超过10页的情况:
    1.从第一页到第6页,点击哪一个页码,这个页码被选中,并且整个分页器没有滚动,没有...省略符;
    2.从第7页到第36页,分页器滚动,所点击的页码始终位于中心位置,且出现...省略符;预定义当前选中页码前面是3个页码(不包含1和...)后面展示4个页码;
    3.从第37页开始往后,分页器不滚动,所点击的页码不位于中心位置;
    :return:

    '''
    html = ''
    if page.paginator.num_pages <= num_total_pages:
        # 分页的总页数不超过10页,不考虑当前点击的页码是否是中心位置了:
        for x in range(1, page.paginator.num_pages+1):
            html += '<li><a href="?page=%s">%s</a></li>' % (x,x)
        return html
    elif page.number <= num_total_pages - num_back_pages:
        for x in range(1, num_total_pages+1):
            html += '<li><a href="?page=%s">%s</a></li>' % (x, x)
        return html
    # (num_total_pages - num_back_pages - 3):预定义当前选中页码前面是3个页码(不包含1和...)
    elif num_total_pages - (num_total_pages - num_back_pages - 3) <= page.number <= page.paginator.num_pages - num_back_pages:
        html += '''
        <li><a href="?page=1">1</a></li>
        <li class="disabled"><a href="?page=%s">...</a></li>
        '''
        # 1...2 3 4 5 6 7 8 9
        for x in range(page.number - (num_total_pages - num_back_pages - 3), page.number + num_back_pages+1):
            html += '<li><a href="?page=%s">%s</a></li>' % (x, x)
        return html
    else:
        # 最后无法滚动的部分
        html += '''
        <li><a href="?page=1">1</a></li>
        <li class="disabled"><a href="?page=%s">...</a></li>
        '''
        for x in range(page.paginator.num_pages -  (num_total_pages - num_back_pages - 3) - num_back_pages, page.paginator.num_pages + 1):
            html += '<li><a href="?page=%s">%s</a></li>' % (x, x)
        return html

模板中:

   <div id="test">
        <ul class="pagination">
			<li>

             {% if page.has_previous %}
                  <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
                  <span aria-hidden="true">&laquo;上一页</span> </a>
              {% endif %}
			</li>


            {% autoescape off %}
                {% custom_paginator page %}
            {% endautoescape %}


			<li>
                {% if page.has_next %}
                  <a href="?page={{ page.next_page_number }}" aria-label="Next">
                  <span aria-hidden="true">下一页&raquo;</span></a>
                {% endif %}


			</li>
        </ul>
    </div>
</div>

使用ajax为点击的页数设置为高亮状态

<script>
    $(document).ready(function () {
        {# each()类似于for循环,找到每一个a标签页码,让这些a标签分别执行each()中的匿名函数。 #}
        $('.pagination > li > a').each(function () {
            {# 获取当前遍历到这个a标签的文本内容,然后和page.number进行比较,如果当前a标签的文本数字和page.number的值相等,就把这个li标记为高亮状态 #}
            {# $(this)指的就是遍历出来的a元素 #}
            if ($(this).html() == {{ page.number }}){
                {# 获取当前a标签的父标签Li,并添加类名active #}
                $(this).parent().addClass('active');
            }
        })
    })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值