详解Django的 paginate_queryset() 函数:对查询结果进行分页

  • Post category:Python

下面是对Django的paginate_queryset()函数的详细讲解:

作用

paginate_queryset()函数是Django内置的分页器函数,主要用于对查询结果进行分页操作。它接受一个queryset对象以及每页显示的条目数量作为参数,并根据参数对queryset进行切片操作,返回一个分页后的结果集合。

使用方法

paginate_queryset()函数通常与Paginator、Page、PageNotAnInteger三个类一同使用,下面分别进行讲解。

Paginator类

我们先来看一下Paginator类的使用方法:

from django.core.paginator import Paginator

# 查找所有的文章对象
articles = Article.objects.all()

# 每页显示5条记录
paginator = Paginator(articles, 5)

# 获取第2页数据,如果不存在就返回空
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)

Paginator类需要传递两个参数:需要进行分页的queryset和每页需显示的条目数量。使用Paginator可以创建一个分页器对象,它有一个get_page()方法,可以通过传递当前页码,返回一个Page对象作为分页后的结果。

Page类

Page类是Paginator类的返回结果,也是paginate_queryset()函数的返回结果。下面是Page类的使用方法:

# 获取当前Page对象的编号以及包含的文章对象列表
current_page_number = page_obj.number
articles = page_obj.object_list

Page类中有一个number属性,表示当前页页码,还有一个object_list属性,包含了分页后的结果列表。

PageNotAnInteger类

由于在进行分页操作时,用户可能传递的页码不是整数(如’abc’),这时会发生错误,为了解决这个问题,Django提供了PageNotAnInteger类,它会帮助我们设置默认的页码。

from django.core.paginator import Paginator, PageNotAnInteger

articles = Article.objects.all()
paginator = Paginator(articles, 5)

# 获取页码数
page_number = request.GET.get('page')

try:
    page_obj = paginator.page(page_number)
except PageNotAnInteger:
    page_obj = paginator.page(1)
except EmptyPage:
    page_obj = paginator.page(paginator.num_pages)

这里使用了try…except…语句,首先尝试将用户传递的页码进行转换,如果无法转换为整数,则将页码设置为第1页(前后端分离编程中,可以将在前端判断、设置为默认值),如果页码超出了总页数,则将页码设置为最后一页。

举例说明

下面提供两个实例来说明paginate_queryset()函数的使用方法:

实例1:简单分页

在一个博客网站中,需要对网站中所有的文章进行分页展示。每页显示10篇文章,要求当用户传递的页码不是整数时,默认展示第一页。使用Django的分页器函数可以轻松实现分页功能,代码如下:

from django.core.paginator import Paginator, PageNotAnInteger

articles = Article.objects.all()
paginator = Paginator(articles, 10)

# 获取页码数
page_number = request.GET.get('page')

try:
    page_obj = paginator.page(page_number)
except PageNotAnInteger:
    page_obj = paginator.page(1)
except EmptyPage:
    page_obj = paginator.page(paginator.num_pages)

实例2:带筛选条件的分页

在一个在线商城网站中,需要对所有商品按价格排序,并根据价格范围进行筛选。每页展示20个商品,要求当用户传递的页码不是整数时,默认展示第一页。使用Django的Q对象进行筛选,再使用分页器函数对商品进行分页展示,代码如下:

from django.db.models import Q
from django.core.paginator import Paginator, PageNotAnInteger

min_price = request.GET.get('min_price', 0)  # 最低价,默认为0
max_price = request.GET.get('max_price', 1000)  # 最高价,默认为1000
search = request.GET.get('search', '')  # 搜索关键词

# 根据条件查询商品
articles = Article.objects.filter(price__gte=min_price, price__lte=max_price)
articles = articles.filter(Q(name__contains=search) | Q(description__contains=search))
articles = articles.order_by('price')

# 每页显示20个商品
paginator = Paginator(articles, 20)

# 获取页码数
page_number = request.GET.get('page')

try:
    page_obj = paginator.page(page_number)
except PageNotAnInteger:
    page_obj = paginator.page(1)
except EmptyPage:
    page_obj = paginator.page(paginator.num_pages)

以上就是对Django的paginate_queryset()函数的作用与使用方法的详细讲解。