玩转Django分页器

news2024/11/23 20:37:32

在这里插入图片描述

一、Pagination 分页器编程步骤

  1. View, 导入django.core.paginator.Paginator类,创建Paginator 对象时,输入qs对象,以及每页显示条数。

  2. 接收 URL, 从请求参数中读取page数值 ,通过 paginator.page(page_num) 返回请求页的page_obj.

  3. 模板中,用page_obj的属性来编写分页器HTML代码

分页器功能的两个主要数据结构: Paginator 对象, Page对象。

参考实例: https://simpleisbetterthancomplex.com/tutorial/2016/08/03/how-to-paginate-with-django.htmlexample

from django.core.paginator import Paginator #import Paginator

def movies(request):
	movies = Movie.objects.all() #queryset containing all movies we just created
	paginator = Paginator(movies, 3)  # 每页3行记录
	page_number = request.GET.get('page')
	page_obj = paginator.get_page(page_number)
	return render(request=request, template_name="main/movies.html", context={'movies':page_obj})

在这里插入图片描述

二、Paginator 对象

paginator 类对象的属性

per_page 每页显示条数。

count, num_pages

page_range, 页面的迭代器

Paginator 对象的方法

Paginator.get_page(number) 返回 page_obj , 页号从1开始

Paginator.page(number) 同上。

三、 Page对象

主要属性

object_list , 即queryset 数据

number, 当前页号

previous_page_number, next_page_number

主要方法

has_next(), has_previous(), next_page_number(), 等, page2.previous_page_number()

>>> page1 = p.page(1)
>>> page1
<Page 1 of 2>
>>> page2 = p.get_page(2)

>>> page2.has_next()
False
>>> page2.has_previous()
True
>>> page2.has_other_pages()
True
>>> page2.next_page_number()
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number()
>>> page2.start_index()  # The 1-based index of the first item on this page
3
>>> page2.end_index()  # The 1-based index of the last item on this page
4

三、分页功能实现

1、URL请求参数携带 page 参数

如:

http://127.0.0.1:8000/books/borrow/?page=1

2、视图中实现分页器,返回页面对象

from django.core.paginator import Paginator #import Paginator

def movies(request):
	movies = Movie.objects.all() #queryset containing all movies we just created
	paginator = Paginator(movies, 10)  # 每页10行记录
	page_number = request.GET.get('page')
	page_obj = paginator.get_page(page_number)
	return render(request=request, template_name="main/movies.html", context={'movies':page_obj})

说明:

 paginator = Paginator(movies, 10)  # 每页10行记录

表示创建分页器对象,构造器传入查询结果,以及每页显示行数。

page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)

请求参数page表示请求的页号,获取该页的页面对象page_obj

return render(request=request, template_name="main/movies.html", context={'movies':page_obj})

将page_obj 页面对象做为context上下文传给模板渲染。

3、模板中实现分页器渲染

数据列表显示部分

page_obj 页面对象中包含了当前页的object对象列表,用 for …in… 遍历。

{% for obj in page_obj %}
   {{ obj.name }} 

{% endfor %}`
分页器栏用用a标签实现分页器跳转

Page对象传入模板后,需要编写html分页器代码,判断是否有上下页, 并传回下次请求的页号

    <div class='pagination'>
        <span class="step-links">
            {% if page_obj.has_previous %}
                <a href="?page=1">&laquo; 首页</a>
                <a href="?page={{ page_obj.previous_page_number }}">上页</a>    
            {% endif %}
            
            <span class="current">
                当前页 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}.
            </span>

            {% if page_obj.has_next %}
                <a href="?page={{ page_obj.next_page_number }}">下页</a>
                <a href="?page={{ page_obj.paginator.num_pages }}">末页 &raquo;</a>
            {% endif %}
    </div>

4、支持用户自定义每页显示行数

有时,用户希望自己控制每页显示行数,可以在GET请求参数中,携带 page_size=xxx, 如

http://127.0.0.1:8000/books/borrow/?page=1&page_size=20

视图函数中,令 paginator.per_page = request.GET[‘page_size’], 即可支持前端修改每页显示条数。

模板中添加1个input标签,监听到 change 事件后,将page_size拼接在地址后面,发送请求到服务器。

    <script>
        var input = document.getElementById("pagesize");
        function handleChange(e){
            window.location.href="http://127.0.0.1:8000/books/borrow/?page=1&page_size="+input.value
        }
    </script>

完整示例代码

views.py

from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import *


def listing(request):
    qs = Borrow.objects.all()
    paginator = Paginator(qs, 25)  # Show 25 contacts per page.
    if 'page_size' in request.GET.keys(): 
        paginator.per_page = request.GET['page_size'],
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)
    return render(request, "list.html", {"page_obj": page_obj})

对于通用视图, 重载get()方法

class BorrowListView(ListView):
    model = Borrow
    template_name = "books/borrow_list.html"
    paginate_by = 10      # 默认传至template的context名称为page_obj

    def get(self, request, *args, **kwargs):
        if 'page_size' in request.GET.keys():
            self.paginate_by = request.GET['page_size']
        return super().get(request, *args, **kwargs)

list_contact.html

{% extends "myapp/base.html" %}

{% block content %}
{% for obj in page_obj %}
    {{ obj.name }}<br>
    ...
{% endfor %}

<div class='pagination'>
        <span class="step-links">
            {% if page_obj.has_previous %}
                <a href="?page=1">&laquo; 首页</a>
                <a href="?page={{ page_obj.previous_page_number }}">上页</a>    
            {% endif %}
            
            <span class="current">
                当前页 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}.
            </span>

            {% if page_obj.has_next %}
                <a href="?page={{ page_obj.next_page_number }}">下页</a>
                <a href="?page={{ page_obj.paginator.num_pages }}">末页 &raquo;</a>
            {% endif %}
            <span style='margin-left: 20px;'>每页显示<span>
            <input type='number' min=10 max=100 id="pagesize" style="width: 40px;" onchange='handleChange()' /><span>条记录</span>

    </div>
    <script>
        var input = document.getElementById("pagesize");
        function handleChange(e){
            window.location.href="http://127.0.0.1:8000/books/borrow/?page=1&page_size="+input.value
        }
    </script>
 {% endblock content %}

最终显示如下
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1559759.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyinstaller打包多线程pyqt5程序后,报错,反复弹窗等问题

报错1&#xff1a; Traceback (most recent call last): File “MPL.py”, line 502, in File “Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_multiprocessing.py”, line 45, in _freeze_support ValueError: not enough values to unpack (expected 2, got 1) 报…

绘制空心环形

1.通过几个div拼接绘制空心环形进度条。 通过 -webkit-mask: radial-gradient(transparent 150px, #fff 150px);绘制空心圆 html:<body><div class"circle"><div class"circle-left"></div><div class"circle-left-mask&…

从0开始搭建基于VUE的前端项目(二) 安装和配置element-ui组件库

版本和地址 ElementUI 2.15.14 (https://element.eleme.io/)按需引入的插件 babel-plugin-component(1.1.1) https://github.com/ElementUI/babel-plugin-component 安装 npm install element-ui完整引入(不建议) 这种方式最后打包的源文件很大&#xff0c;造成网络资源的浪…

LeetCode-56. 合并区间【数组 排序】

LeetCode-56. 合并区间【数组 排序】 题目描述&#xff1a;解题思路一&#xff1a;排序&#xff1f;怎么排&#xff1f;当然是排各个区间的左边界&#xff0c;然后判断下一个边界的左边界与结果数组里面的右边界是否重叠。解题思路二&#xff1a;优化解题思路三&#xff1a;0 题…

Vitepress部署到GitHub Pages,工作流

效果&#xff1a; 第一步&#xff1a; 部署 VitePress 站点 | VitePress 执行 npm run docs:build&#xff0c;npm run docs:preview&#xff0c;生成dist文件 第二步&#xff1a; 手动创建.gitignore文件&#xff1a; node_modules .DS_Store dist-ssr cache .cache .temp *…

[html]基础知识点汇总

前言 经过一阵子学习后&#xff0c;把知识点全部提炼了出来&#xff0c;自我感觉比较全和简洁&#xff0c;希望能够帮到大家。 本机实验环境 火狐浏览器&#xff0c;vscode&#xff0c;windows11&#xff0c;程序运行插件&#xff1a;live server html介绍 html--前端语言…

深入PostgreSQL中的pg_global表空间

pg_global表空间的位置 在PG当中&#xff0c;一个实例(cluster)初始化完以后&#xff0c;你会看到有下边两个与表空间相关的目录生成&#xff1a; $PGDATA/base $PGDATA/global 我们再用元命令\db以及相关视图看看相应的表空间信息&#xff1a; postgres# \db …

synchronized 关键字 - 监视器锁 monitor lock

目录 一、1 synchronized 的特性 1、互斥 2、可重入 二、synchronized 使用示例 1、修饰代码块: 明确指定锁哪个对象. 2、直接修饰普通⽅法: 锁的 SynchronizedDemo 对象 3、修饰静态方法: 锁的 SynchronizedDemo 类的对象 我们重点要理解&#xff0c;synchronized 锁…

Java设计模式 | 原型模式

是什么 用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象。该模式的核⼼思想是基于现有的对象创建新的对象&#xff0c;⽽不是从头开始创建。 结构 抽象原型接口&#xff1a;声明一个克隆自身的方法clone()具体原型类&#xf…

飞书API(2):通过 Python 读取多维表数据

上一篇介绍了怎么通过官方的控制台调用飞书的 API 读取多维表数据&#xff0c;本篇介绍怎么通过 Python 读取多维表数据。 通过 Python 读取多维表主要分两步&#xff1a; 第一步是获取 access_token&#xff1b;第二步是拿 access_token 读取数据。 先说第二步&#xff0c;因…

SQLAlchemy 建立数据库模型之间的关系

常见关系&#xff1a; 一对多关系多对一关系多对多关系一对一关系 一对多关系&#xff08;一个作者&#xff0c;多篇文章&#xff09; ## 一对多关系&#xff0c;单作者-多文章&#xff0c;外键不可少 ## 外键(ForeignKey)总在多的那边定义,关系(relationship)总在单的那边定…

【计算机网络】四层负载均衡和七层负载均衡

前言 1、分层方式 首先我们知道&#xff0c;在计算机网络中&#xff0c;常用的协议分层方式&#xff1a;OSI和TCP/IP&#xff0c;以及实际生产中使用的协议划分方式。 在OSI中&#xff0c;各层的职责如下&#xff1a; 应用层&#xff1a;对软件提供接口以使程序能使用网络服…

CVAE——生成0-9数字图像(Pytorch+mnist)

1、简介 CVAE&#xff08;Conditional Variational Autoencoder&#xff0c;条件变分自编码器&#xff09;是一种变分自编码器&#xff08;VAE&#xff09;的变体&#xff0c;用于生成有条件的数据。在传统的变分自编码器中&#xff0c;生成的数据是完全由潜在变量决定的&…

9.图像中值腐蚀膨胀滤波的实现

1 简介 在第七章介绍了基于三种卷积前的图像填充方式&#xff0c;并生成了3X3的图像卷积模板&#xff0c;第八章运用这种卷积模板进行了均值滤波的FPGA实现与MATLAB实现&#xff0c;验证了卷积模板生成的正确性和均值滤波算法的MATLAB算法实现。   由于均值滤波、中值滤波、腐…

【QT+QGIS跨平台编译】054:【exiv2lib+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、exiv2lib介绍二、文件下载三、文件分析四、pro文件五、编译实践一、exiv2lib介绍 exiv2lib 是一个用于处理图像元数据的开源 C++ 库。它可用于读取、编辑和写入图像文件中的 Exif 元数据(Exchangeable Image File Format,可交换图像文件格式)…

怎么打包出release.aar包

第一种 选择build variant 更改成release 第二钟 在gradle中选择相应任务来编译 选择assemble release如果没有这个选项&#xff0c;可能是你没有开启那个Task 收集的选项

机器学习——降维算法-奇异值分解(SVD)

机器学习——降维算法-奇异值分解&#xff08;SVD&#xff09; 在机器学习中&#xff0c;降维是一种常见的数据预处理技术&#xff0c;用于减少数据集中特征的数量&#xff0c;同时保留数据集的主要信息。奇异值分解&#xff08;Singular Value Decomposition&#xff0c;简称…

为 Linux 中的 Docker 配置阿里云和网易云国内镜像加速下载中心

由于默认情况下&#xff0c;Docker 的镜像下载中心默认为国外的镜像中心&#xff0c;使用该镜像中心拉去镜像会十分缓慢&#xff0c;所以我们需要配置国内的 Docker 镜像下载中心&#xff0c;加速 Docker 镜像的拉取。Docker 的国内镜像下载中心常用的有&#xff1a;阿里云、网…

微信小程序(黑马优购:购物车页面)

1.渲染商品页面 <template><view><!-- 商品列表的标题区域 --><view class"cart-title"><!-- 左侧的图标 --><uni-icons type"shop" size"18"></uni-icons><!-- 右侧的文本 --><text class…

力扣 1143. 最长公共子序列

题目来源&#xff1a;https://leetcode.cn/problems/longest-common-subsequence/description/ C题解&#xff08;思路来源代码随想录&#xff09;&#xff1a;动态规划。 1. 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j]&#xff1a;长度为[0, i - 1]…