paginate_queryset()
函数是 Django 框架中用来实现分页功能的函数。它的主要作用是将一个可迭代的对象进行分页处理,返回当前页的数据以及上一页和下一页页码的信息。搭配着 Django 自带的分页器 Paginator
和视图 ListView
使用,是一个非常方便的分页工具。
函数签名
def paginate_queryset(self, queryset, page_size):
"""
Paginate the queryset, if needed.
If the queryset is already sliced, it can be used as-is.
"""
queryset
: 要进行分页的对象,一般是 QuerySet。page_size
: 每页的数据条数。
使用方法
我们主要使用 Django 自带的 Paginator
和视图 ListView
来使用 paginate_queryset()
函数。
在一般的视图函数中使用:
from django.core.paginator import Paginator
from django.shortcuts import render
def myview(request):
queryset = MyModel.objects.all()
paginator = Paginator(queryset, 20) # 每页显示20条数据
page = request.GET.get('page')
queryset = paginator.get_page(page)
return render(request, 'my_template.html', {'queryset': queryset})
在类视图 ListView
中使用:
from django.core.paginator import Paginator
from django.views.generic import ListView
from myapp.models import MyModel
class MyListView(ListView):
model = MyModel
template_name = 'my_template.html'
context_object_name = 'queryset'
paginate_by = 20
def get_queryset(self):
queryset = super().get_queryset()
page = self.request.GET.get('page')
paginator = Paginator(queryset, self.paginate_by)
queryset = paginator.get_page(page)
return queryset
在以上示例代码中,我们都通过 Paginator
来将数据进行分页处理,并通过 paginate_queryset()
函数进行分页操作。其中,ListView
已经默认实现了分页逻辑,我们只需要设置好 paginate_by
属性即可。
实例演示
以用户表为例,假设有 30 条记录,我们将其默认每页显示 10 条。
# views.py
from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import User
def user_list(request):
users = User.objects.all()
# 分页操作
paginator = Paginator(users, 10)
page_num = request.GET.get('page')
page_users = paginator.get_page(page_num)
return render(request, 'user_list.html', {'users': page_users})
<!-- templates/user_list.html -->
{% extends 'base.html' %}
{% block content %}
{% for user in users %}
<p>{{ user.username }}</p>
{% endfor %}
<!-- 显示分页链接 -->
<div class="pagination">
<span class="step-links">
{% if users.has_previous %}
<a href="?page=1">« 第一页</a>
<a href="?page={{ users.previous_page_number }}">上一页</a>
{% endif %}
<span class="current-page">
第{{ users.number }}页,共{{ users.paginator.num_pages }}页
</span>
{% if users.has_next %}
<a href="?page={{ users.next_page_number }}">下一页</a>
<a href="?page={{ users.paginator.num_pages }}">最后一页 »</a>
{% endif %}
</span>
</div>
{% endblock %}
我们请求 user_list
视图页面,输出如下:
user1
user2
user3
user4
user5
user6
user7
user8
user9
user10
此时页面下方会展示分页链接,如下所示:
<< 第一页, < 上一页, 第1页,共3页, 下一页 >, 最后一页 >>
作为第二个实例,如果我们有基于类视图的用户表视图,则可以使用 ListView 视图进行渲染页面。代码如下:
from django.core.paginator import Paginator
from django.views.generic import ListView
from myapp.models import User
class UserListView(ListView):
model = User
template_name = 'user_list.html'
context_object_name = 'users'
paginate_by = 10
def get_queryset(self):
return super().get_queryset().order_by('id')
这样与普通函数类似, ListView 视图会自动进行分页和展示分页链接等操作。