Django-分页
后端分页
Django提供了Paginator
类来实现后端分页。Paginator
类可以将一个查询集(QuerySet)分成多个页面,每个页面包含指定数量的对象。
from django.shortcuts import render, redirect, get_object_or_404
from .models import User
from .forms import UserForm
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
'''
用户列表
'''
def user_list(request):
user_list = User.objects.all()
# 处理自定义值
try:
# 获取用户选择的每页显示数量,默认为 10
per_page = int(request.GET.get('per_page', 10))
per_page = int(per_page) # 将 per_page 转换为整数
if per_page <= 0: # 如果输入的值小于等于0,设置为默认值10
per_page = 10
except (ValueError, TypeError): # 如果 per_page 不是数字,设置为默认值10
per_page = 10
# 分页
paginator = Paginator(user_list, per_page)
page_number = request.GET.get('page')
try:
page_obj = paginator.get_page(page_number) # 获取当前页
except PageNotAnInteger: # 如果 page 不是整数,跳转到第一页
page_obj = paginator.get_page(1)
except EmptyPage: # 如果 page 超出范围,跳转到最后一页
page_obj = paginator.get_page(paginator.num_pages)
# 允许的每页显示数量列表
allowed_per_page = [10, 20, 50, 100, 200]
return render(request, 'myapp/user_list.html', {
'page_obj': page_obj,
'per_page': per_page, # 将每页显示数量传递给模板
'allowed_per_page': allowed_per_page,
})
前端分页
通用前端的分页代码支持输入页码,也支持选择页码,跳转到对应页面
<nav aria-label="Page navigation" class="mt-4">
<ul class="pagination justify-content-center">
<!-- 首页按钮 -->
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1&per_page={{ per_page }}" aria-label="First">
<span aria-hidden="true">首页</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">首页</span>
</li>
{% endif %}
<!-- 上一页按钮 -->
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}&per_page={{ per_page }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">上一页</span>
</li>
{% endif %}
<!-- 当前页码信息 -->
<li class="page-item active">
<span class="page-link">
第 {{ page_obj.number }} 页,共 {{ page_obj.paginator.num_pages }} 页
</span>
</li>
<!-- 下一页按钮 -->
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}&per_page={{ per_page }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">下一页</span>
</li>
{% endif %}
<!-- 末页按钮 -->
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}&per_page={{ per_page }}" aria-label="Last">
<span aria-hidden="true">末页</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">末页</span>
</li>
{% endif %}
</ul>
<!-- 输入页码跳转和选择每页显示数量 -->
<div class="d-flex justify-content-center mt-3">
<!-- 输入页码跳转 -->
<form method="get" action="" class="form-inline mr-3">
<div class="input-group">
<input type="number" name="page" class="form-control" min="1" max="{{ page_obj.paginator.num_pages }}"
placeholder="页码" aria-label="页码" required>
<input type="hidden" name="per_page" value="{{ per_page }}">
<div class="input-group-append">
<button type="submit" class="btn btn-outline-primary">跳转</button>
</div>
</div>
</form>
<!-- 选择每页显示数量 -->
<form method="get" action="" class="form-inline">
<div class="input-group">
<select name="per_page" class="form-control" aria-label="每页显示数量" onchange="this.form.submit()">
<option value="10" {% if per_page == 10 %}selected{% endif %}>10 条/页</option>
<option value="20" {% if per_page == 20 %}selected{% endif %}>20 条/页</option>
<option value="50" {% if per_page == 50 %}selected{% endif %}>50 条/页</option>
<option value="100" {% if per_page == 100 %}selected{% endif %}>100 条/页</option>
<option value="200" {% if per_page == 200 %}selected{% endif %}>200 条/页</option>
<option value="1" {% if per_page != 10 and per_page != 20 and per_page != 50 and per_page != 100 and per_page != 200 %}selected{% endif %}>自定义</option>
</select>
{% if per_page != 10 and per_page != 20 and per_page != 50 and per_page != 100 and per_page != 200 %}
<input type="number" name="per_page" class="form-control ml-2" min="1"
value="{{ per_page }}" placeholder="自定义" aria-label="自定义" required>
{% endif %}
</div>
</form>
</div>
</nav>