关于python:Django笔记三十四之分页操作

2次阅读

共计 3141 个字符,预计需要花费 8 分钟才能阅读完成。

这一篇笔记介绍一下如何在 Django 应用分页。

Django 自带一个分页的模块:

from django.core.paginator import Paginator

主要用途是列表数据的切割,比如说有 3000 条用户数据,前端须要一个列表接口用于展现这些数据,然而一次性展示这么多数据不适合,所以打算用分页的形式来操作。

比方一页 20 条数据,前端通过按钮管制 page_num 和 size 参数用于后端返回数据。

以下是本篇笔记目录:

  1. 间接分页操作
  2. Paginator 分页操作
  3. Paginator 其余函数
  4. Page 的其余操作

1、间接分页操作

在介绍 Django 的分页模块前,咱们个别如果要分页的话会如何操作呢,这里咱们定义 page_num 参数为 页数,size 参数为一页返回的数据量。

假如有这样一个长度为 20 的列表:

data_list = list(range(20))

咱们想要实现每页三条数据,也就是 size = 3,咱们依据 page_num 和 size 参数能够这样操作:

target_list = data_list[(page_num - 1) * size: page_num * size]

因为页数是从 1 开始的,而列表的下标是从 0 开始的,所以这里是 page_num – 1。

以这个为例,咱们接下来介绍一下如何应用 Django 的模块来操作分页。

2、Paginator 分页操作

Paginator 不仅能够用于 model 的 queryset 数据,也能够用于咱们下面这种列表数据 data_list,咱们这里应用 data_list 作为示例。

以下是一个简略的应用 Paginator 的示例:

from django.core.paginator import Paginator

data_list = list(range(20))
page_num = 1
size = 3

paginator = Paginator(data_list, size)

target_page_data = paginator.page(page_num)
# <Page 1 of 7>

for item in target_page_data:
    print(item)
    
count = paginator.count

在下面的示例中,Paginator() 办法接管须要分页的可迭代数据,能够是这里的列表,也能够是 Django 里的 QuerySet 类型,而后通过 .page() 函数指定 page_num 数就能够获取指定页数的数据。

另外,如果须要获取总数,能够间接 .count 获取接管的可迭代数据的总数。

分页超出总页数

比方后面咱们依据 size 大小对数据进行了分页,最多只能分为 7 页,然而前面咱们的 page 数传入的是 7,会怎么办呢?会报错:

    raise EmptyPage(_('That page contains no results'))
django.core.paginator.EmptyPage: That page contains no results

如何躲避这种状况呢,当然,前端在传入的时候能够做肯定的限度,然而后端也要有这样的管制,能够在传入 page_num 参数前就对数据做一个校验,发现 page_num 超出总页数则间接 raise 报错返回前端,或者间接传入 page_num,通过 try except 来管制,发现报错的话,间接返回空列表,比方:

data_list = list(range(20))
page_num = 10
size = 3

paginator = Paginator(data_list, size)

try:
    target_page_data = paginator.page(page_num)
except:
    target_page_data = []
    
count = paginator.count

3、Paginator 其余函数

get_page(number)

后面咱们对于每页数据的获取有一个 try except 的操作:

try:
    target_page_data = paginator.page(page_num)
except:
    target_page_data = []

假如说咱们的数据只能分 7 页数据,那么 paginator.page(page_num) 的 page_num 参数就只能在 1-7 之间,能够是 int,也能够是字符串的 1-7,比方 “2”,除此之外输出的其余参数,比方 0,-1,或者其余非法字符串都会引发报错。

所以咱们应用了一个 try except 操作来捕捉异样,当产生异样时,咱们返回的是空列表。

get_page() 函数相当于是基于 page() 函数做了异样解决,当咱们输出的数据是非法整数时,比方页数在 1-7 之间,咱们输出的是 0,或者 -1,或者 10,返回的则是最初一页数据:

>>> paginator.get_page(99)
<Page 7 of 7>

如果咱们输出的是其余的非法数据的时候,返回的则是第一页数据:

>>> paginator.get_page('a')
<Page 1 of 7>

count 属性

后面介绍了,能够通过 paginator.count 的形式来拿到待分页的数据的总数,这里介绍一下 .count 实现的形式。

因为 Paginator 是既能够对列表类型数据进行分页,也能够对 QuerySet 进行分页,然而 QuerySet 有 .count() 函数,而列表数据是没有这个操作的。

然而如果对立都用 len() 函数来对输出的数据进行取长度,这又是不事实的,因为 len() 函数的操作流程会将 QuerySet 数据都加载而后取值,在 QuerySet 无比大的时候这又是不事实的,这一点在之前的 Django 查问优化笔记中有记录。

所以这里的 count 背地的办法是先去查看这个数据有没有 count() 办法,有的话就执行,比方一个 QuerySet,没有的话就执行 len() 函数,比方列表数据。

num_pages 属性

返回总页数,比方咱们后面的示例返回的数据是 7:

paginator.num_pages
# 7

page_range 属性

返回页数范畴,是一个 range() 类型:

paginator.page_range

4、Page 的其余操作

这里的 Page 指的是分页后的一页数据的 Page 类型,也就是后面咱们定义的 target_page_data 数据:

target_page_data = paginator.page(page_num)

是否有前一页

>>> target_page_data.has_previous()
# True

是否有后一页

>>> target_page_data.has_next()
# True

获取下一页的页数

>>> target_page_data.next_page_number()
# 2

获取前一页的页数

target_page_data.next_page_number()

留神 :如果当前页在第一页或者最初一页,当咱们应用获取前一页或者下一页的页数时会报错。

当前页的开始和完结索引

对于某页数据,如果想获取该页数据在全副数据中的索引,比如说,对于一个长度为 20 的列表进行分页,每页数量为 4,获取的是第 1 页的数据,那么这页数据的开始和完结索引就在 1 和 4,因为这里定义的索引是从 1 开始计算的。

>>> target_page_data = paginator.page(1)
>>> 
>>> target_page_data.start_index()
# 1
>>> target_page_data.end_index()
# 4

当前页数

获取当前页数:

target_page_data.number

获取当前页数据列表

>>> target_page_data.object_list
[12, 13, 14]

本文首发于自己微信公众号:Django 笔记。

原文链接:Django 笔记三十四之分页操作

如果想获取更多相干文章,可扫码关注浏览:

正文完
 0