下面是小凰凰的简介,看下吧!
人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活
学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习中)
您的点赞、收藏、关注是对博主创作的最大鼓励,在此谢过!
有相关技能问题可以写在下方评论区,我们一起学习,一起进步。
后期会不断更新python全栈学习笔记,秉着质量博文为原则,写好每一篇博文。
class Pagination(object):
def __init__(self, total_count, current_page, per_page_item_num=10, max_page_num=7):
# 数据总个数
self.total_count = total_count
# 当前页
try:
v = int(current_page)
if v <= 0:
v = 1
self.current_page = v
except Exception as e:
self.current_page = 1
# 每页显示的行数
self.per_page_item_num = per_page_item_num
# 最多显示页数
self.max_page_num = max_page_num
def start(self):
return (self.current_page - 1) * self.per_page_item_num
def end(self):
return self.current_page * self.per_page_item_num
@property
def num_pages(self):
"""
总页数
:return:
"""
# 666
# 10
a, b = divmod(self.total_count, self.per_page_item_num)
if b == 0:
return a
return a + 1
def pager_num_range(self):
# self.num_pages()
# self.num_pages
# 当前页
# self.current_page
# 最多显示的页码数量 11
# self.per_pager_num
# 总页数
# self.num_pages
if self.num_pages < self.max_page_num:
return range(1, self.num_pages + 1)
# 总页数特别多 5
part = int(self.max_page_num / 2)
if self.current_page <= part:
return range(1, self.max_page_num + 1)
if (self.current_page + part) > self.num_pages:
return range(self.num_pages - self.max_page_num + 1, self.num_pages + 1)
return range(self.current_page - part, self.current_page + part + 1)
def page_str(self):
page_list = []
first = "首页 "
page_list.append(first)
if self.current_page == 1:
prev = "上一页 "
else:
prev = "上一页 " % (self.current_page - 1,)
page_list.append(prev)
for i in self.pager_num_range():
if i == self.current_page:
temp = "%s " % (i, i)
else:
temp = "%s " % (i, i)
page_list.append(temp)
if self.current_page == self.num_pages:
nex = "下一页 "
else:
nex = "下一页 " % (self.current_page + 1,)
page_list.append(nex)
last = "尾页 " % (self.num_pages,)
page_list.append(last)
return ''.join(page_list)
这个文件就是分页用的,以后我们哪个python项目要用分页直接把这个放进去就行!
上面这个Pagination类怎么用呢?在哪里用呢?
在views.py里用
,用法如下:
@transaction.atomic
def book_view(request):
from app01.pager import Pagination
total_count = Book.objects.all().count()
current_page = request.GET.get('page')
page_obj = Pagination(total_count, current_page, max_page_num=11)
book_list = Book.objects.all()[page_obj.start(): page_obj.end()]
start = page_obj.start() + 1
for book_obj in book_list: # 把书籍编号放进对象中,方便前端取
book_obj.nid = start
start += 1
return render(request, 'index.html', {
'book_list': book_list, 'page_obj': page_obj, 'username':request.user})
只需要把book_view视图函数一改就行!
path('', views.book_view, name='book_view'),
和分页有关的就这一个路由!
Pagination类中有这么一个函数,如果你的路由不是主页,而是其他如:
path('index/', views.book_view, name='book_view'),
那么你需要改这个函数,如下:
def page_str(self):
page_list = []
first = "首页 "
page_list.append(first)
if self.current_page == 1:
prev = "上一页 "
else:
prev = "上一页 " % (self.current_page - 1,)
page_list.append(prev)
for i in self.pager_num_range():
if i == self.current_page:
temp = "%s " % (i, i)
else:
temp = "%s " % (i, i)
page_list.append(temp)
if self.current_page == self.num_pages:
nex = "下一页 "
else:
nex = "下一页 " % (self.current_page + 1,)
page_list.append(nex)
last = "尾页 " % (self.num_pages,)
page_list.append(last)
return ''.join(page_list)
你需要把里面的href都改了,改成href='/index/?page=%s'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{
% block page_title %}
<title>图书管理系统</title>
{
% endblock %}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.table_area {
width: 800px;
position: absolute;
top: 150px;
left: 250px;
}
.add_btn {
font-size: 18px;
font-family: "Kaiti SC";
font-weight: bolder;
}
.sys-menu {
position: relative;
top: auto;
left: 35px;
width: 150px;
height: 200px;
}
.page_top {
background-color: #146896;
width: 100%;
height: 50px;
}
.panel-heading {
text-align: center;
font-weight: bolder;
}
.panel-body {
text-align: center;
width: 100%;
}
.panel-body > a {
text-decoration: none;
}
.panel-body > a:hover {
color: skyblue;
}
.active {
background-color: blanchedalmond;
}
#exampleModalLabel {
font-family: "Kaiti SC";
font-size: 20px;
font-weight: bolder;
}
.login-area {
margin-right: 20px;
}
.modify-key, .login_out, .user-name, .head-img {
float: right;
color: skyblue;
margin-right: 15px;
}
.modify-key:hover, .login_out:hover {
color: red;
text-decoration: none;
cursor: pointer;
}
.page_top > div {
position: relative;
top: 15px;
}
.head-img {
width: 45px;
height: 45px;
border-radius: 45px;
overflow: hidden;
position: relative;
top: -12px;
border: 2px solid white;
}
.user-name {
font-family: "Kaiti SC";
font-weight: bolder;
}
.head-img > img {
width: 100%;
}
#warning-key {
color: red;
font-family: "Kaiti SC";
}
.split_page_area {
line-height: 100%;
text-align: center;
margin-top: -30px;
margin-bottom: -30px;
}
</style>
</head>
<body>
<div class="page_top">
<div class="login-area">
<a type="button" class=" modify-key" data-toggle="modal" data-target="#exampleModal"
data-whatever="@mdo">修改密码
</a>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="exampleModalLabel">密码修改</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="old_secret" class="control-label">原密码</label>
<input type="password" class="form-control" id="old_secret">
</div>
<div class="form-group">
<label for="new_secret" class="control-label">新密码</label>
<input type="password" class="form-control" id="new_secret">
</div>
<div class="form-group">
<label for="re_new_secret" class="control-label">
确认新密码 <span id="warning-key"></span>
</label>
<input type="password" class="form-control" id="re_new_secret">
</div>
<div class="modal-footer">
<button id="sub-mdkey" type="button" class="btn btn-primary login-btn"
data-dismiss="modal">提交
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<a class="login_out" href="{% url 'login_out' %}">注销</a>
<span class="user-name">{
{
username }}</span>
<div class="head-img">
<img src="http://127.0.0.1:8000/static/img/head-img.jpg" alt="">
</div>
</div>
</div>
<div class="panel panel-default sys-menu">
<div class="panel-heading">
功能系统
</div>
{
% block sys_view %}
<div class="panel-body active">
<a href="{% url 'book_view' %}">图书管理系统</a>
</div>
<div class="panel-body">
<a href="{% url 'author_view' %}">作者管理系统</a>
</div>
<div class="panel-body">
<a href="{% url 'publisher_view' %}">出版社管理系统</a>
</div>
{
% endblock %}
</div>
{
% block master_content %}
<div class="table_area">
{
% csrf_token %}
<table class="table table-hover">
<thead>
<tr>
<th>书籍编号</th>
<th>书名</th>
<th>价格</th>
<th>出版时间</th>
<th>出版社</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{
% for book_obj in book_list %}
<tr>
<td>{
{
book_obj.nid }}</td>
<td>{
{
book_obj.name }}</td>
<td>{
{
book_obj.price }}</td>
<td>{
{
book_obj.pub_date|date:'Y-m-d' }}</td>
<td>{
{
book_obj.publish.name }}</td>
<td>
{
% for author_obj in book_obj.authors.all %} <!--book_obj.authors.all得到的是一个作者对象的queryset-->
{
% if forloop.last %}
<!--
有人会问这里不是对象吗?为什么打印对象?不应该是author_obj.name吗?
我在model中写了双下方法str的
-->
{
{
author_obj }}
{
% else %}
{
{
author_obj }},
{
% endif %}
{
% endfor %}
</td>
<td>
<a href="{% url 'book_edit' book_obj.pk %}" class="btn btn-warning btn-xs">编辑</a>
<!-- 删除我们应该使用ajax进行局部刷新,不应该和编辑一样使用页面刷新 -->
<a id="del_book" class="btn btn-danger btn-xs" book_id={
{
book_obj.pk }}>删除</a>
</td>
</tr>
{
% if forloop.last and forloop.counter > 0 %}
<tr>
<td colspan="7">
<div class="split_page_area">
<ul class="pagination pagination-md">
{
{
page_obj.page_str|safe }}
</ul>
</div>
</td>
</tr>
<tr>
<td colspan="7">
<a href="{% url 'book_add' %}" class="btn btn-info btn-xs form-control add_btn">添加书籍</a>
</td>
</tr>
{
% endif %}
{
% empty %}
<tr align="center">
<td colspan="7">
暂未上架任何书籍... <br>
<span>请点击:<a href="{% url 'book_add' %}" class="btn btn-info btn-xs">添加书籍</a></span>
</td>
</tr>
{
% endfor %}
</tbody>
</table>
</div>
{
% endblock %}
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
{
% block script_area %}
<script>
$(function () {
$("tbody").on('click', '#del_book', function () {
let $ele = $(this).parent().parent()
$.ajax({
url: `/books/del/${
$(this).attr('book_id')}/`,
type: "post",
data: {
csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
},
success: function (response) {
response = JSON.parse(response)
if (response["status"] == true) {
$ele.remove()
} else {
alert('书籍删除失败!请重试')
}
}
})
})
$('#re_new_secret').blur(function () {
let re_val = $(this).val()
let val = $('#new_secret').val()
if (re_val != val) {
$('#warning-key').text('两次密码输入不一致,请重新输入')
setTimeout(function () {
$('#warning-key').text('')
}, 3000)
}
})
$('.login-btn').click(function () {
$.ajax({
url: '{% url 'secret_modify' %}',
type: 'post',
data: {
old_secret: $('#old_secret').val(),
new_secret: $('#new_secret').val()
},
success: function (response) {
if (response == 'ok') {
alert('密码修改成功!')
setTimeout(function () {
location.href = "{% url 'login_view' %}"
}, 3000)
} else {
alert('密码修改失败!')
}
}
})
})
})
</script>
{
% endblock %}
</html>
{
% for book_obj in book_list %}
<tr>
# 书籍编号采用新加的nid,使得即使分页,每页之间编号都是连续的!
<td>{
{
book_obj.nid }}</td>
</tr>
{
% if forloop.last and forloop.counter > 0 %}
<tr>
<td colspan="7">
<div class="split_page_area">
# 这里就是核心的分页器,外层div主要起个布局定位作用
<ul class="pagination pagination-md">
{
{
page_obj.page_str|safe }}
</ul>
</div>
</td>
</tr>
<tr>
<td colspan="7">
<a href="{% url 'book_add' %}" class="btn btn-info btn-xs form-control add_btn">添加书籍</a>
</td>
</tr>
{
% endif %}