Django笔记三十四之分页操作

科技资讯 投稿 23900 0 评论

Django笔记三十四之分页操作

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

Django 自带一个分页的模块:

from django.core.paginator import Paginator

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

以下是本篇笔记目录:

    直接分页操作
  1. Paginator 分页操作
  2. Paginator 其他函数
  3. Page 的其他操作

1、直接分页操作

假设有这样一个长度为 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。

2、Paginator 分页操作

Paginator 不仅可以用于 model 的 queryset 数据,也可以用于我们上面这种列表数据 data_list,我们这里使用 data_list 作为示例。

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 数就可以获取指定页数的数据。

分页超出总页数

比如前面我们根据 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,或者其他非法字符串都会引发报错。

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 实现的方式。

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

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(

注意:如果当前页在第一页或者最后一页,当我们使用获取前一页或者下一页的页数时会报错。

当前页的开始和结束索引

>>> 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笔记三十四之分页操作

赞同 (111) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽