Frontend - 分页(针对 python / Django )

目录

一、同个文件内(方式一)

1. 前端 html

2. 定义分页界面

3. 获取分页数据

4.后端根据前端分页需求,整理分页数据

5.显示情况

6. JsonResponse 相关知识

二、不同文件内依旧有效(方式二,更优化)

1. 前端html

2. 定义分页界面(可放在独立的js文件内,可作为公共方法)

3. 获取分页数据(和html同文件)

4. 后端根据前端分页需求,整理分页数据

5. 显示情况


该分页功能是针对Django的Paginator、JsonResponse的回传方式,以及前端Ajax的POST请求。

一、同个文件内(方式一)

1. 前端 html

<div class="table_content table_border H_percent_60">
    <table id="dt_list" class="table table-striped table_view ">
        <thead>
            {% for c in col %} <!-- col是get请求时返回的标题列表-->
            <th>{{ c }}</th>
            {% endfor %}
        </thead>
    </table>
     <!-- 分页 -->
    <div class="dataTables_wrapper"> <!-- 自定义datatable的分页-->
        <div class="row" style="padding-right: 15px;">
            <div class="dataTables_paginate paging_simple_numbers" id="dt_list_paginate">
                <ul id="id_page" class="pagination"></ul>
            </div>
        </div>
    </div>
</div>

2. 定义分页界面

function get_page_html(paginationElement, totalPages, currentPage){
    paginationElement.innerHTML = '';
    // 上一页按钮
    let prevLi = document.createElement('li');  // li标签(排列)
    let prevLink = document.createElement('a'); // a标签(显示文字+绑定点击事件)
    prevLink.textContent = 'Previous'; // 设置显示文字(必须是字符串)
    prevLink.onclick = () => {
        if (currentPage > 1) {
            currentPage--; //只作用于onclick方法中(currentPage在onclick方法外时,没有减1)
        }
        get_query_data(currentPage); // 执行上一页数据的请求
        return false; // 避免a标签#默认跳转
    };
    prevLi.className = 'paginate_button'; // 设置样式(比如和dataTable的显示样式一致)
    prevLi.appendChild(prevLink); // 将a标签插入li标签
    paginationElement.appendChild(prevLi);// 将li标签插入总分页结构
    
    // 首页页码按钮
    let firstPageNumberLi = document.createElement('li');
    let firstPageNumberLink = document.createElement('a');
    firstPageNumberLink.textContent = '1';
    firstPageNumberLink.onclick = () => {
        get_query_data(1); // 执行第一页数据的请求
        return false;
    };
    if (currentPage === 1) { // active 设置当前页的li标签高亮
        firstPageNumberLi.className = 'paginate_button active';
    } else {
        firstPageNumberLi.className = 'paginate_button';
    }
    firstPageNumberLi.appendChild(firstPageNumberLink);
    paginationElement.appendChild(firstPageNumberLi);
    
    // 针对省略号按钮、数字按钮
    let startPage = Math.max(2, currentPage - 3);  // 其中,3是设置当前页码左边的显示个数
    let endPage = Math.min(totalPages-1, currentPage + 3); // 其中,3是设置当前页码右边的显示个数
    
    // 省略号按钮
    if (startPage > 2) {
        let pageNumberLi = document.createElement('li');
        let pageNumberLink = document.createElement('a');
        pageNumberLink.textContent = '...';
        // pageNumberLi.className = 'paginate_button disabled'; // 设置按钮是datatable的button样式、不可操作的样式(不可操作的样式设置好后,下面的onclick事件就需要注释掉)
        pageNumberLink.onclick = () => {
            get_query_data(startPage);// 执行省略号某页数据的请求
            return false;
        };
        pageNumberLi.className = 'paginate_button';
        pageNumberLi.appendChild(pageNumberLink);
        paginationElement.appendChild(pageNumberLi);
    }
    
    // 数字按钮
    for (let i = startPage; i <= endPage; i++) {
        let pageNumberLi = document.createElement('li');
        let pageNumberLink = document.createElement('a');
        pageNumberLink.textContent = i.toString();
        pageNumberLink.onclick = () => {
            get_query_data(i);// 执行某页数据的请求
            return false;
        };
        if (i === currentPage) {
            pageNumberLi.className = 'paginate_button active';// 设置按钮是datatable的button样式、高亮的样式(className样式的名称需同时设置,用空格隔开,而不能分开多次设置,只会最后一次生效)
        } else {
            pageNumberLi.className = 'paginate_button';
        }
        pageNumberLi.appendChild(pageNumberLink);
        paginationElement.appendChild(pageNumberLi);
    }
    
    // 省略号按钮
    if (endPage < totalPages-1) {
        let pageNumberLi = document.createElement('li');
        let pageNumberLink = document.createElement('a');
        pageNumberLink.textContent = '...';
        pageNumberLink.onclick = () => {
            get_query_data(endPage);// 执行省略号某页数据的请求
            return false;
        };
        pageNumberLi.className = 'paginate_button';
        pageNumberLi.appendChild(pageNumberLink);
        paginationElement.appendChild(pageNumberLi);
    }
        
    // 尾页页码按钮
    let totalPageNumberLi = document.createElement('li');
    let totalPageNumberLink = document.createElement('a');
    totalPageNumberLink.textContent = totalPages.toString(); // 设置显示文字(必须是字符串)
    totalPageNumberLink.onclick = () => {
        get_query_data(totalPages); // 执行最后一页数据的请求
        return false;
    };
    if (currentPage === totalPages) { // active 设置当前页的li标签高亮
        totalPageNumberLi.className = 'paginate_button active';
    } else {
        totalPageNumberLi.className = 'paginate_button';
    }
    totalPageNumberLi.appendChild(totalPageNumberLink);
    paginationElement.appendChild(totalPageNumberLi);
    
    // 下一页按钮
    let nextLi = document.createElement('li');
    let nextLink = document.createElement('a');
    nextLink.textContent = 'Next';
    nextLink.onclick = () => {
        if (currentPage < totalPages) {
            currentPage++;//只作用于onclick方法中(currentPage在onclick方法外时,没有递增1)
        }
        get_query_data(currentPage); // 执行下一页数据的请求
        return false;
    };
    nextLi.className = 'paginate_button';
    nextLi.appendChild(nextLink);
    paginationElement.appendChild(nextLi);
}

3. 获取分页数据

var paginationElement = document.getElementById('id_page'); // 分页
$("#id_btn").click(function () {
     get_query_data(1); // 点击查询,默认显示首页数据
});

function get_query_data(currentPage) {
   $.ajax({
        url: window.location.pathname, 
        type: "POST",
        data: {
            "currentPage":currentPage, //当前页码
        },
        beforeSend: function () {
            $("#id_btn").attr({ disabled: true });
        },
        success: function (reply) {
            if (reply.result) {
                let page_data = reply.data['page_data']; //分页功能所需数据
                get_page_html(paginationElement, page_data['all_pages_num'], page_data['current_page_num']) // 执行分页。参数分别为分页组件、分页数据的总页码、当前页码
            }
	             else {
                 paginationElement.innerHTML = ''; // 不显示分页器
            }
        },
        complete: function () {
            $("#id_btn").attr({ disabled: false });
        },
    });
}

4.后端根据前端分页需求,整理分页数据

from django.core.paginator import Paginator #分页所需依赖
class test(View):
    # 只是部分代码    
    def post(self, request):
        try:
            # 获取基本信息
           data = request.POST
		   res_list = [[1,"数据结构","教育",45.00], [1,"数据库原理","教育",34.00]]
                    paginator = Paginator(res_list, 10) # 分页器(10是当前页显示的行数)
           current_page_num = int(data.get('currentPage', 1)) # 当前页码
           page_data = {'all_pages_num': paginator.num_pages, # 总页数
                        'current_page_num': current_page_num, # 当前页码
                        'current_page_data': paginator.page(current_page_num).object_list} # 当前呈现数据
           return JsonResponse(page_data)

 5.显示情况

6. JsonResponse 相关知识

Backend - Django JsonResponse & HttpResponse_django jsonresponse safe-CSDN博客 

二、不同文件内依旧有效(方式二,更优化)

1. 前端html

<div class="table_content table_border H_percent_60">
    <table id="dt_list" class="table table-striped table_view ">
        <thead>
            {% for c in col %} <!-- col是get请求时返回的标题列表-->
            <th>{{ c }}</th>
            {% endfor %}
        </thead>
    </table>
    <!-- 分页 -->
    <div class="dataTables_wrapper"> <!-- 自定义datatable的分页-->
        <div class="row" style="padding-right: 15px;">
            <div class="dataTables_paginate paging_simple_numbers" id="dt_list_paginate">
                <ul id="id_page" class="pagination"></ul>
            </div>
        </div>
    </div>
</div>

2. 定义分页界面(可放在独立的js文件内,可作为公共方法)

/**
 * dataTable 分页(给页码标签增添点击事件、设置样式)
 * @pagination_ele 页码功能的位置 
 * @show_txt li标签显示的文字
 * @style_name li标签的样式
 * @is_click 是否添加点击事件 
 * @current_page 点击事件中跳转的页码值
 * @get_query_data 执行的方法
 * @return pagination_ele
 */
function set_dt_pagination(pagination_ele, show_txt, style_name, is_click=false, current_page=1, get_query_data=null){
    let eleLi = document.createElement('li');
    let eleLink = document.createElement('a');
    eleLink.textContent = show_txt;
    if(is_click){
        eleLink.onclick = () => {
            get_query_data(current_page); // get_query_data并没有立马被调用,而是定义在onclick中,只有用户点击时才真正的被触发。
            return false;
        };
    }
    eleLi.className = style_name;
    eleLi.appendChild(eleLink);
    pagination_ele.appendChild(eleLi);
    return pagination_ele;
}

/**
 * dataTable 分页(设置页码标签位置、判断当前页码)
 * @paginationElement 需要渲染的分页组件
 * @totalPages 总页数 
 * @currentPage 当前页码
 * @get_query_data 执行的方法
 */
function get_page_html(paginationElement, totalPages, currentPage, get_query_data){
    paginationElement.innerHTML = '';
    // 上一页按钮
    let prePage = currentPage;
    if (currentPage > 1) {
        prePage = currentPage-1;
    }
    paginationElement = set_dt_pagination(paginationElement, 'Previous', 'paginate_button', true, prePage, get_query_data); // get_query_data不能加括号,只是传递方法
    
    // 首页页码按钮            
    if (currentPage === 1) { // active 设置当前页的li标签高亮
        style_name = 'paginate_button active';
    } else {
        style_name = 'paginate_button';
    }
    paginationElement = set_dt_pagination(paginationElement, '1', style_name, true, 1, get_query_data); // get_query_data不能加括号,只是传递方法
    // 针对省略号按钮、数字按钮
    let startPage = Math.max(2, currentPage - 1);
    let endPage = Math.min(totalPages-1, currentPage + 1);
    // 左边的省略号按钮(可点击)
       if (startPage > 2) {
        // paginationElement = set_dt_pagination(paginationElement, '...', 'paginate_button disabled'); // 设置按钮是datatable的button样式、不可点击的样式
        paginationElement = set_dt_pagination(paginationElement, '...', 'paginate_button', true, startPage, get_query_data);
    }
    // 数字按钮
    for (let i = startPage; i <= endPage; i++) {              
        if (currentPage === i) { // active 设置当前页的li标签高亮
            style_name = 'paginate_button active';
        } else {
            style_name = 'paginate_button';
        }
        paginationElement = set_dt_pagination(paginationElement, i.toString(), style_name, true, i, get_query_data); // get_query_data不能加括号,只是传递方法
    }
    // 右边的省略号按钮(可点击)
    if (endPage < totalPages-1) {
        // paginationElement = set_dt_pagination(paginationElement, '...', 'paginate_button disabled'); // 设置按钮是datatable的button样式、不可点击的样式
        paginationElement = set_dt_pagination(paginationElement, '...', 'paginate_button', true, endPage, get_query_data);
    }
    
    // 尾页页码按钮           
    if (currentPage === totalPages) { // active 设置当前页的li标签高亮
        style_name = 'paginate_button active';
    } else {
        style_name = 'paginate_button';
    }
    paginationElement = set_dt_pagination(paginationElement, totalPages.toString(), style_name, true, totalPages, get_query_data); // get_query_data不能加括号,只是传递方法
    // 下一页按钮
    let nextPage = currentPage;
    if (currentPage < totalPages) {
        nextPage = currentPage+1;
    }
    paginationElement = set_dt_pagination(paginationElement, 'Next', 'paginate_button', true, nextPage, get_query_data); // get_query_data不能加括号,只是传递方法
}

3. 获取分页数据(和html同文件)

var paginationElement = document.getElementById('id_page'); // 分页。对应模板的id_page的组件
$("#id_btn").click(function () {
     get_query_data(1); // 点击查询,默认显示首页数据
});
function get_query_data(currentPage) {
   $.ajax({
        url: window.location.pathname, 
        type: "POST",
        data: {
            "currentPage":currentPage, //当前页码
        },
        beforeSend: function () {
            $("#id_btn").attr({ disabled: true });
        },
        success: function (reply) {
            if (reply.result) {
                let page_data = reply.data['page_data']; //分页功能所需数据
                get_page_html(paginationElement, page_data['all_pages_num'], page_data['current_page_num'], get_query_data) // 执行分页。参数分别为分页组件、分页数据的总页码、当前页码、分页方法(第四个参数get_query_data保证在不同js代码文件中也能执行。看似运用了递归,但其实在get_page_html中并没有立马调用它,而是onclick规定只有用户点击时才真正的被触发)
            } else {
                 paginationElement.innerHTML = ''; // 不显示分页器
             }
        },
        complete: function () {
            $("#id_btn").attr({ disabled: false });
        },
    });
}

4. 后端根据前端分页需求,整理分页数据

from django.core.paginator import Paginator #分页所需依赖
class test(View):
    # 只是部分代码    
    def post(self, request):
        try:
            # 获取基本信息
           data = request.POST
		   res_list = [[1,"数据结构","教育",45.00], [1,"数据库原理","教育",34.00]]
                    paginator = Paginator(res_list, 10) # 分页器(10是当前页显示的行数)
           current_page_num = int(data.get('currentPage', 1)) # 当前页码
           page_data = {'all_pages_num': paginator.num_pages, # 总页数
                        'current_page_num': current_page_num, # 当前页码
                        'current_page_data': paginator.page(current_page_num).object_list} # 当前呈现数据
return JsonResponse(page_data)

5. 显示情况

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

骑行解压:身心的奇妙之旅,VELO Angel Revo坐垫

在快节奏的都市生活中&#xff0c;骑行不仅是一种健康的生活方式&#xff0c;更是一种心灵的释放。从心理生理学的角度来看&#xff0c;骑行能够促使身体分泌内啡肽&#xff0c;带来愉悦感&#xff0c;同时&#xff0c;它还能转移注意力&#xff0c;缓解焦虑。在这场身心的奇妙…

HarmonyOS NEXT 实战之元服务:静态案例效果---教育培训服务

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; import { authentication } …

使用JMeter对Linux生产服务器进行压力测试

安装 JMeter wget https://downloads.apache.org/jmeter/binaries/apache-jmeter-5.4.1.tgz tar -xzf apache-jmeter-5.4.1.tgz cd apache-jmeter-5.4.1创建 JMeter 脚本 设置中文 选择Options—>Choose Language—>选择其他语言&#xff08;例如&#xff1a;Chinese&am…

【Web安全】文件写入漏洞 ASP 网页病毒模拟(文件写入漏洞+FilesystemObject)

【Web安全】文件写入漏洞 ASP 网页病毒模拟&#xff08;文件写入漏洞FilesystemObject&#xff09; 原理 文件写入漏洞 文件写入漏洞是指攻击者通过某种方式在服务器上创建或修改文件的漏洞。攻击者可以利用此漏洞在服务器上写入恶意代码或文件&#xff0c;从而实现进一步的…

微信小程序调用 WebAssembly 烹饪指南

我们都是在夜里崩溃过的俗人&#xff0c;所幸终会天亮。明天就是新的开始&#xff0c;我们会变得与昨天不同。 一、Rust 导出 wasm 参考 wasm-bindgen 官方指南 https://wasm.rust-lang.net.cn/wasm-bindgen/introduction.html wasm-bindgen&#xff0c;这是一个 Rust 库和 CLI…

整合版canal ha搭建--基于1.1.4版本

开启MySql Binlog&#xff08;1&#xff09;修改MySql配置文件&#xff08;2&#xff09;重启MySql服务,查看配置是否生效&#xff08;3&#xff09;配置起效果后&#xff0c;创建canal用户&#xff0c;并赋予权限安装canal-admin&#xff08;1&#xff09;解压 canal.admin-1…

药片(药丸)和胶囊识别数据集,使用yolo,pasical voc xml, coco json格式标注,可识别药片和胶囊两种标签,2445张原始图片

药片(药丸)和胶囊识别数据集&#xff0c;使用yolo&#xff0c;pasical voc xml, coco json格式标注&#xff0c;可识别药片和胶囊两种标签&#xff0c;2445张原始图片 数据集分割 训练组80&#xff05; 1967图片 有效集13% 317图片 测试集7% 161图片 预处…

C 语言:注释的重要性及用法详解

目录 一、注释的作用 二、C 语言中的注释类型 三、注释的实践 四、注释的注意事项 五、总结 在 C 语言编程中&#xff0c;注释是一种非常重要的工具&#xff0c;它可以帮助程序员更好地理解代码、提高代码的可读性和可维护性。本文将详细介绍 C 语言中注释的用法和重要性。…

麒麟信安云在长沙某银行的应用入选“云建设与应用领航计划(2024)”,打造湖湘金融云化升级优质范本

12月26日&#xff0c;2024云计算产业和标准应用大会在北京成功召开。大会汇集政产学研用各方专家学者&#xff0c;共同探讨云计算产业发展方向和未来机遇&#xff0c;展示云计算标准化工作重要成果。 会上&#xff0c;云建设与应用领航计划&#xff08;2024&#xff09;建云用…

LeetCode - 初级算法 数组(存在重复元素)

存在重复元素 这篇文章讨论如何判断一个数组中是否存在重复元素。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定一个整数数组 nums,如果任一值在数组中出现至少两次,返回 true;如果数组中每个元素互不相同,返回 false。 示例: 输入: nums =…

C++笔记之尾后迭代器

C笔记之尾后迭代器 code review! 参考笔记 1.C笔记之尾后迭代器 2.C笔记之迭代器失效问题处理 在C中&#xff0c;尾后迭代器&#xff08;通常称为 past-the-end iterator&#xff09;是指指向容器中最后一个元素之后的位置的迭代器。它并不指向任何有效的元素&#xff0c;而是…

Gibbs现象(Gibbs Phenomenon)最初数学上的定义

Gibbs现象&#xff08;Gibbs Phenomenon&#xff09;是在处理周期性信号的傅里叶级数展开时出现的一种现象。当一个周期函数在不连续点附近被其傅里叶级数的部分和近似时&#xff0c;近似值会在不连续点处产生过冲&#xff08;overshoot&#xff09;和欠冲&#xff08;undersho…

【时时三省】(C语言基础)动态内存函数realloc

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 realloc realloc函数的出现让动态内存管理更加灵活。 有时会我们发现过去申请的空间太小了&#xff0c;有时候我们又会觉得申请的空间过大了&#xff0c;那为了合理的时候内存&#xff0c;…

pycharm+anaconda创建项目

pycharmanaconda创建项目 安装&#xff1a; Windows下PythonPyCharm的安装步骤及PyCharm的使用-CSDN博客 详细Anaconda安装配置环境创建教程-CSDN博客 创建项目&#xff1a; 开始尝试新建一个项目吧&#xff01; 选择好项目建设的文件夹 我的项目命名为&#xff1a;pyth…

ActiveMQ支持哪些传输协议

ActiveMQ 支持多种传输协议&#xff0c;以满足不同场景下的需求。这些协议包括但不限于以下几种&#xff1a; 1. OpenWire&#xff1a; • 这是 ActiveMQ 的默认和专有协议。 • 提供了高效、可靠的消息传递功能。 • 支持多种消息传递模式&#xff0c;如点对点和发布/订阅。 2…

Spring SpEL表达式由浅入深

标题 前言概述功能使用字面值对象属性和方法变量引用#this 和 #root变量获取类的类型调用对象(类)的方法调用类构造器类型转换运算符赋值运算符条件(关系)表达式三元表达式Elvis 操作符逻辑运算instanceof 和 正则表达式的匹配操作符 安全导航操作员数组集合(Array 、List、Map…

STM32裸机开发转FreeRTOS教程

目录 1. 简介2. RTOS设置&#xff08;1&#xff09;分配内存&#xff08;2&#xff09;查看任务剩余空间&#xff08;3&#xff09;使用osDelay 3. 队列的使用&#xff08;1&#xff09;创建队列&#xff08;1&#xff09;直接传值和指针传值&#xff08;2&#xff09;发送/接收…

第9章图9.15-9.21-《分析模式》原图和UML图对比

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集

提升口语发音水平,中英文发音评测系统实现

在全球化的浪潮中&#xff0c;语言不再是障碍&#xff0c;而是连接世界的桥梁。掌握一门流利的英语&#xff0c;意味着打开了通往世界的大门。但是&#xff0c;如何确保你的英语口语如同母语者一样自然流畅&#xff1f;这正是我们存在的意义。 我们的中英文口语发音评测服务&a…