- 分页器
- 话不多说...写他*的
- Django分页器使用
- 终极分页器使用
- 前端使用ajax后端写成装饰器
-曾老湿, 江湖人称曾老大。
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
分页器
分页器介绍 |
---|
介绍个p啊,不就是一堆数据不放在一页显示,放在好几页嘛...
具体长啥样?每个网站都不一样...
大概就是 ... 这样

在页面显示分页数据,需要用到Django分页器组件
导入分页模块 |
---|
from django.core.paginator import Paginator
Paginator对象: paginator = Paginator(user_list, 10)
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
page对象:page=paginator.page(1)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
话不多说...写他*的
创建项目 |
---|
连接数据库创建表,直接使用sqllite数据库
代码语言:javascript复制DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
创建一张表,往里面多写点数据,然后我们才好分页
代码语言:javascript复制from django.db import models
# Create your models here.
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
数据库迁移
代码语言:javascript复制MacBook-pro:fenye driverzeng$ python3 manage.py makemigrations app0
MacBook-pro:fenye driverzeng$ python3 manage.py migrate

批量插入数据 |
---|
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
]
代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
def index(request):
## 以前写法
# for i in range(100):
# models.Book.objects.create(name='图书%s' % i, price=10 i)
## 现在写法(批量插入)
# 1.先造出100本书,放到列表中
l = []
for i in range(100):
l.append(models.Book(name='图书%s' % i, price=10 i))
# 批量插入,第一个参数插入的对象,第二个参数,每一次插入多少条(不写则全插)
models.Book.objects.bulk_create(l, 10)
return HttpResponse('ok')

一访问页面,100条数据就进去了。

现在写index页面,返回数据
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书 分页</title>
</head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<body>
<div class="container-fluid">
<nav class="navbar navbar-default navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="你要找啥啊?">
</div>
<button type="submit" class="btn btn-default">搜索图书</button>
</form>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table table-hover">
<thead>
<tr>
<th>书名</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

添加前端分页 |
---|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书 分页</title>
</head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<body>
<div class="container-fluid">
<nav class="navbar navbar-default navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="你要找啥啊?">
</div>
<button type="submit" class="btn btn-default">搜索图书</button>
</form>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table table-hover">
<thead>
<tr>
<th>书名</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>

Django分页器使用
代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator # 导入分页器的类
def index(request):
book_list = models.Book.objects.all()
# 实例化产生一个对象
## 两个参数
# 1.第一个是对象列表
# 2.第二个是每页的条数
paginator=Paginator(book_list,10)
## 数据总条数
print(paginator.count)
## 总页数 (10页)
print(paginator.num_pages)
## 页码数列表
print(paginator.page_range)
## 取到第x页,返回一个对象
current_page = paginator.page(5)
## 当前页面的数据
print(current_page.object_list)
## 是否有下一页
print(current_page.has_next())
## 是否有上一页
print(current_page.has_previous())
## 下一页页码数
print(current_page.next_page_number())
## 上一页页码数
print(current_page.previous_page_number())
return render(request,'index.html',locals())

代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator # 导入分页器的类
def index(request):
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 10)
current_page_num = int(request.GET.get('page'))
current_page = paginator.page(current_page_num)
## 当前页码所有数据
print(current_page.object_list)
# 既可以循环 current_page.pbject_list,又可以循环当前页的对象
for item in current_page:
print(item.name)
return render(request, 'index.html', locals())

目前只能通过浏览器传递数据,查看到后台内容,现在去修改前端。
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书 分页</title>
</head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<body>
<div class="container-fluid">
<nav class="navbar navbar-default navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="你要找啥啊?">
</div>
<button type="submit" class="btn btn-default">搜索图书</button>
</form>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table table-hover">
<thead>
<tr>
<th>书名</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for book in current_page %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if current_page.has_previous %}
<li>
{#<a href="/index/?page={{ current_page_num|add:-1 }}" aria-label="Previous">#}
<a href="/index/?page={{ current_page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% else %}
<li class="disable">
{#<a href="/index/?page={{ current_page_num|add:-1 }}" aria-label="Previous">#}
<a href="" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% endif %}
{% for total_page in paginator.page_range %}
{% if current_page_num == total_page %}
<li class="active"><a href="/index/?page={{ total_page }}">{{ total_page }}</a></li>
{% else %}
<li><a href="/index/?page={{ total_page }}">{{ total_page }}</a></li>
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<li>
<a href="/index/?page={{ current_page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% else %}
<li class="disable">
<a href="" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>


终极分页器使用
刚才的代码是有bug的,我们来解决一下bug,如果我们手动改浏览器中的?page=100000000,程序就炸了。Boom~~~~~~

不管输入多少,都跳转到最后一页
代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator,EmptyPage # 导入分页器的类
def index(request):
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 10)
try:
current_page_num = int(request.GET.get('page'))
current_page = paginator.page(current_page_num)
## 当前页码所有数据
# print(current_page.object_list)
# 既可以循环 current_page.pbject_list,又可以循环当前页的对象
# for item in current_page:
# print(item.name)
except EmptyPage as e:
# 捕获异常后跳转到最后一页
current_page_num = paginator.num_pages
current_page = paginator.page(current_page_num)
return render(request, 'index.html', locals())

但是还tmd有bug,我们在后端用int转了数据,但是如果调皮的用户们,输入的是字母或者特殊符号,int没有办法转...程序还是会炸。

继续捕获异常
代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator,EmptyPage # 导入分页器的类
def index(request):
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 10)
try:
current_page_num = int(request.GET.get('page'))
current_page = paginator.page(current_page_num)
## 当前页码所有数据
# print(current_page.object_list)
# 既可以循环 current_page.pbject_list,又可以循环当前页的对象
# for item in current_page:
# print(item.name)
except Exception as e:
# 捕获异常后跳转到最后一页
current_page_num = paginator.num_pages
current_page = paginator.page(current_page_num)
return render(request, 'index.html', locals())

现在bug是没有了,但是还有一个问题 ... 我们现在网页显示的是10条,10条的话,看起来还阔以噻~
但是如果我们每页显示3条咋整?感受一下?

尼玛~ 丑的不要不要的啊。改tmd
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书 分页</title>
</head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<body>
<div class="container-fluid">
<nav class="navbar navbar-default navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="你要找啥啊?">
</div>
<button type="submit" class="btn btn-default">搜索图书</button>
</form>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table table-hover">
<thead>
<tr>
<th>书名</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for book in current_page %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if current_page.has_previous %}
<li>
{#<a href="/index/?page={{ current_page_num|add:-1 }}" aria-label="Previous">#}
<a href="/index/?page={{ current_page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% else %}
<li class="disabled">
{#<a href="/index/?page={{ current_page_num|add:-1 }}" aria-label="Previous">#}
<a href="" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% endif %}
{% for total_page in page_range %}
{% if current_page_num == total_page %}
<li class="active"><a href="/index/?page={{ total_page }}">{{ total_page }}</a></li>
{% else %}
<li><a href="/index/?page={{ total_page }}">{{ total_page }}</a></li>
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<li>
<a href="/index/?page={{ current_page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>
代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator,EmptyPage # 导入分页器的类
def index(request):
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 3)
# 如果页码数多,让他显示前五,后五,中间是当前在的页码
try:
current_page_num = int(request.GET.get('page'))
page_range = range(current_page_num - 5, current_page_num 6)
current_page = paginator.page(current_page_num)
except Exception as e:
current_page_num = paginator.num_pages
current_page = paginator.page(current_page_num)
return render(request, 'index.html', locals())

诶?看起来好像是可以了。。。。。可以个锤子哦。
请看下图...这特么的是啥?

代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator,EmptyPage # 导入分页器的类
def index(request):
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 3)
# 如果页码数多,让他显示前五,后五,中间是当前在的页码
try:
current_page_num = int(request.GET.get('page'))
current_page = paginator.page(current_page_num)
except Exception as e:
current_page_num = 1
current_page = paginator.page(current_page_num)
if paginator.num_pages > 11:
if current_page_num - 5 < 1:
page_range = range(1, 12)
elif current_page_num 5 > paginator.num_pages:
page_range = range(paginator.num_pages - 11, paginator.num_pages 1)
else:
page_range = range(current_page_num - 5, current_page_num 6)
else:
page_range = paginator.page_range
return render(request, 'index.html', locals())

前端使用ajax后端写成装饰器
代码语言:javascript复制from django.shortcuts import render, HttpResponse
# Create your views here.
from app01 import models
from django.core.paginator import Paginator,EmptyPage # 导入分页器的类
import json
def auth_ajax(func):
def inner(request,*args,**kwargs):
request.data = request.POST
try:
request.data = json.loads(request.body.decode('utf-8'))
except Exception as e:
print(e)
res = func(request,*args,**kwargs)
return res
return inner
@auth_ajax
def index(request):
if request.method == 'GET':
return render(request,'index.html')
elif request.method == 'POST':
print(request.data)
return HttpResponse('OK')
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书分页AJAX</title>
</head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<body>
<button id="btn">点我</button>
<script>
$('#btn').click(function () {
var dic = {'name':'zls'}
var da = JSON.stringify(dic)
$.ajax({
url: '/index/',
type: 'post',
contentType: 'application/json',
data:da,
success:function (data) {
console.log(data)
}
})
})
</script>
</body>
</html>