论述
flask通过flask-sqlalchemy建立模型后,将数据库的数据查询出来传递到模板中,由于有时候数据很多,需要进行分页查询,自己动手写一个分页很麻烦。可以通过flask-sqlalchemy自带的分页功能或者flask-pagination、flask-pagninate等插件进行分页。
创建数据库
复制 create database pagination charset=utf8;
配置数据库
复制 from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
HOSTNAME = "127.0.0.1"
PORT = "3306"
DATABASE = "pagination"
USERNAME = "root"
PASSWORD = "123456"
DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8".format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI
# 屏蔽SQLalchemy发送的信号
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)
定义模型
复制 class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(200),)
age = db.Column(db.Integer,)
创建数据
通过python shell进行交互创建数据
复制 from app import *
db.create_all()
如果出现如下错误
复制 'No application found. Either work inside a view function or push'。。。
则应该这样写
接下来进行创建数据
复制 from app import *
with app.app_context():
for i in range(1000):
user = UserModel(name="user{}".format(i),age=i%100)
db.session.add(user)
db.session.commit()
查看数据从第10行开始的10条数据
分页操作
flask-sqlalchemy的分页功能
通过flask-sqlalchemy自带的分页功能进行分页
定义视图函数
复制 @app.route('/')
def index():
# 获取页码,page是分页操作中默认的参数
page = request.args.get("page",default=1,type=int)
# 获取sqlalchemy对象
objs = UserModel.query.order_by(UserModel.name.desc())
# 获取pagination对象
pagination = objs.paginate(page, per_page=10, error_out = False)
# 通过pagination对象的items方法返回当前页的内容列表
users = pagination.items
# pagination对象能够进行分页
data = {
"users":users,
"pagination":pagination,
}
return render_template("index.html",**data)
iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2)
迭代分页中的页码,四个参数,分别控制了省略号左右两侧各显示多少页码,在模板中可以这样渲染
定义模板
index.html
复制 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div data-gb-custom-block data-tag="for">
{{ item.name }} -- {{ item.age }} <br>
</div>
<div data-gb-custom-block data-tag="set" data-endpoint='index'></div>
<ul class="pagination">
{# 没有前一页,添加class=disble,不可点击,a href=##}
<li
<div data-gb-custom-block data-tag="if"> class="disabled"</div>>
<a href="<div data-gb-custom-block data-tag="if"></div>{{ url_for(endpoint, page=pagination.prev_num)}}<div data-gb-custom-block data-tag="else">#</div>">
«
</a>
</li>
<div data-gb-custom-block data-tag="for"></div>
<div data-gb-custom-block data-tag="if"></div>
<div data-gb-custom-block data-tag="if">
<li class="active">
<a href="{{ url_for(endpoint, page = p)}}">{{ p }}</a>
</li>
<div data-gb-custom-block data-tag="else">
<li>
<a href="{{ url_for(endpoint, page = p) }}">{{ p }}</a>
</li>
</div>
<div data-gb-custom-block data-tag="else">
<li class="disabled"><a href="#">…</a></li>
</div>
</div>
{# 没有后一页,添加class=disble,不可点击,a href=##}
<li
<div data-gb-custom-block data-tag="if"> class="disabled"</div>>
<a href="<div data-gb-custom-block data-tag="if"></div>{{ url_for(endpoint, page=pagination.next_num) }}<div data-gb-custom-block data-tag="else">#</div>
">
»
</a>
</li>
</ul>
</body>
</html>
可以将分页的部分抽离出来放在macro模板中,这样其他页面需要分页的时候,就能直接调用时候了,不用在写一次了。
_macro.html
复制 <div data-gb-custom-block data-tag="macro"></div>
<ul class="pagination">
{# 没有前一页,添加class=disble,不可点击,a href=##}
<li
<div data-gb-custom-block data-tag="if"> class="disabled"</div>>
<a href="<div data-gb-custom-block data-tag="if"></div>{{ url_for(endpoint, page=pagination.prev_num)}}<div data-gb-custom-block data-tag="else">#</div>">
«
</a>
</li>
<div data-gb-custom-block data-tag="for"></div>
<div data-gb-custom-block data-tag="if"></div>
<div data-gb-custom-block data-tag="if">
<li class="active">
<a href="{{ url_for(endpoint, page = p)}}">{{ p }}</a>
</li>
<div data-gb-custom-block data-tag="else">
<li>
<a href="{{ url_for(endpoint, page = p) }}">{{ p }}</a>
</li>
</div>
<div data-gb-custom-block data-tag="else">
<li class="disabled"><a href="#">…</a></li>
</div>
</div>
{# 没有后一页,添加class=disble,不可点击,a href=##}
<li
<div data-gb-custom-block data-tag="if"> class="disabled"</div>>
<a href="<div data-gb-custom-block data-tag="if">{{ url_for(endpoint, page=pagination.next_num) }}<div data-gb-custom-block data-tag="else">#</div>
">
»
</a>
</li>
</ul>
</div>
index.html
复制 <div data-gb-custom-block data-tag="import" data-0='_macro.html'></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div data-gb-custom-block data-tag="for">
{{ item.name }} -- {{ item.age }} <br>
</div>
{{ macros.render_pagination(pagination=pagination,endpoint="index") }}
</body>
</html>
安装
复制 pip install flask-paginate
导入模块
复制 from flask_paginate import Pagination,get_page_parameter
get_page_parameter()
这个默认值为 page
, 也就是分页编号, 表示当前是第几页
定义视图函数
复制 @app.route('/')
def index(per_page=10):
# 获取页码,page是分页操作中默认的参数
page = request.args.get(get_page_parameter(),type=int,default=1)
offset = (page-1)*per_page
count = offset + per_page
# 获取sqlalchemy对象
objs = UserModel.query
"""
objs = UserModel.query.all()[offset:count]
"""
# 用户数据
users = objs.offset(offset).limit(per_page).all()
# 获取总数
total = objs.count()
# 获取pagination对象
pagination = Pagination(bs_version=3, page=page, total=total, outer_window=0, inner_window=2)
data = {
"users":users,
"pagination":pagination,
}
return render_template("index.html",**data)
Pagination(bs_version=3, page=page, total=total, outer_window=0, inner_window=2)
中需要添加outer_window=0, inner_window=2
这样能够渲染按钮。
Pagination(page=,total=,bs_version=,search=,record_name=,outer_window=,inner_window=)
page=
当前是第几页; total=
数据总量; bs_version=
这个就是 bootstrap
的版本号了, 默认值是2 ;search=
是否是搜索, pagination.info
格式化时文案会不一样 ;record_name=
展示文案 pagination.info
中的值;设置outer_window
,inner_window
能够渲染按钮
更改CSS样式
可以根据需求调整
复制 .pagination-page-info {
padding: .6em;
padding-left: 0;
width: 40em;
margin: .5em;
margin-left: 0;
font-size: 12px;
}
.pagination-page-info b {
color: black;
background: #6aa6ed;
padding-left: 2px;
padding: .1em .25em;
font-size: 150%;
}
定义模板
复制 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
</head>
<body>
<div data-gb-custom-block data-tag="for">
{{ user.name }} -- {{ user.age }} <br>
</div>
{{ pagination.info }}
{{ pagination.links }}
</body>
</html>