当前位置 主页 > 服务器问题 > Linux/apache问题 >

    通过 Django Pagination 实现简单分页功能

    栏目:Linux/apache问题 时间:2019-11-12 19:32

    作者:HelloGitHub-追梦人物

    文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库

    当博客上发布的文章越来越多时,通常需要进行分页显示,以免所有的文章都堆积在一个页面,影响用户体验。

    Django 内置的 Pagination 能够帮助我们实现简单的分页功能,在上一篇教程中我们使用脚本批量生成了几百篇博客文章,正好用于测试分页效果。

    Paginator 类的常用方法

    分页功能由 Django 内置的 Paginator 类提供,这个类位于 django.core.paginator 模块,需要使用它时,只需在适当的地方导入这个类即可:

    from django.core.paginator import Paginator

    下面的代码摘自 Django 的官方文档中 Pagination 的示例,只需实例化一个 Paginator 对象,并在实例化时传入一个需要分页的列表对象,就可以得到分页后的对象。

    # 对 item_list 进行分页,每页包含 2 个数据。
    >>> item_list = ['john', 'paul', 'george', 'ringo']
    >>> p = Paginator(item_list, 2)

    取特定页的数据:

    # 取第 2 页的数据
    >>> page2 = p.page(2)
    >>> page2.object_list
    ['george', 'ringo']

    查询特定页的当前页码数:

    >>> page2.number
    2

    查看分页后的总页数:

    >>> p.num_pages
    2

    查看某一页是否还有上一页,以及查询该页上一页的页码:

    # 查询第二页是否还有上一页
    >>> page2.has_previous()
    True
    
    # 查询第二页上一页的页码
    >>> page2.previous_page_number()
    1

    查看某一页是否还有下一页,以及查询该页下一页的页码:

    # 查询第二页是否还有下一页
    >>> page2.has_next()
    False
    
    # 查询第二页下一页的页码
    >>> page2.next_page_number()
    Traceback (most recent call last):
    ...
    EmptyPage: That page contains no results

    更多方法和属性请参阅 Django Pagination 的官方文档。

    用 Paginator 给文章列表分页

    使用上面的一些方法,我们可以实现一个类似于 Django 官方博客一样的简单分页效果,效果如下。

    这里 Django 的官方文档中给出了一个在视图函数中对列表进行分页的示例,这个视图函数获取一个联系人列表并对其分页:

    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.shortcuts import render
    
    def listing(request):
      contact_list = Contacts.objects.all()
      paginator = Paginator(contact_list, 25) # 每页显示 25 个联系人
    
      page = request.GET.get('page')
      try:
        contacts = paginator.page(page)
      except PageNotAnInteger:
        # 如果用户请求的页码号不是整数,显示第一页
        contacts = paginator.page(1)
      except EmptyPage:
        # 如果用户请求的页码号超过了最大页码号,显示最后一页
        contacts = paginator.page(paginator.num_pages)
    
      return render(request, 'list.html', {'contacts': contacts})

    这就是在视图函数中使用分页的代码逻辑,你可以把它当做一个模板应用于自己的任何需要分页的视图函数。不过在我们的博客项目中,我们不必写这些代码了。回顾在 Django 官方推荐的姿势:类视图 中的内容,我们已将视图函数转换成了类视图。而类视图