目录
一、同个文件内(方式一)
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)