Flask查询以及分页
以动物类做例子
下面创建动物的表
class Animal(db.Model):
id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
a_name = db.Column(db.String(32))
a_age = db.Column(db.Integer, default=1)
def save(self):
db.session.add(self)
db.session.commit()
下面定义了一个save方法
使我们在定义完对象之后,可以直接调用save方法去存储对象
django中存储对象的时候就是对象.save(),这里就是把flask中添加对象并且提交封装成了save()函数,使我们去调用save函数从而添加并且提交对象
路由:
@app.route('/add_animal/')
flask中路由跟django中的路由有一点不同,flask中路由以装饰器的形式直接写在视图函数上面,而django是从urls文件中单独去写路由,各有利弊。前者比较直观在那个视图函数上方就是那个的路由,不容易搞混,因为可能一个app路由有很多个,但是不利于查找,反而第二种方法,把路由统一存在一个urls文件中,这样方便管理,查找起来也不是很麻烦。
视图函数:
def add_animal():
name = request.args.get("name")
age = request.args.get("age")
animal = Animal()
animal.a_name = name
animal.a_age = age
animal.save()
return "动物添加成功"
flask中的视图函数跟django中的视图函数没什么不同。不同的点就是django中request.GET.get(),这里就是request.args.get()。
下面是查询:
animals = Animal.query.all()
animals = Animal.query.filter(Animal.a_age <= 3)
animals = Animal.query.filter(Animal.a_age.__le__(3))
animals = Animal.query.filter(Animal.a_name.contains("小"))
animals = Animal.query.filter(Animal.a_age.in_([1,2,3,4,5,6,7,8,18]))
#limit 和 offset不区分顺序,一定先执行 offset,后执行 limit order_by 必须在limit和offset之前去调用
animals = Animal.query.order_by(text("-a_age")).limit(3)
# flask 中的所有配置文件
print(current_app.config)
for key in current_app.config:
print(key, current_app.config.get(key))
return render_template("Animals.html", animals=animals)
通过affset和limit来分页
#分页 每一页有多少 第几页
per_page = int(request.args.get("per_page") or 3)
page = int(request.args.get("page") or 1)
animals = Animal.query.limit(per_page).offset((page-1) * per_page)
使用flask自带的pagination去写分页的视图函数与路由:
@app.route('/animals/')
def animals():
# pagination = Animal.query.filter(or_(Animal.a_age.__gt__(18), Animal.a_age.__lt__(5))).paginate()
pagination = Animal.query.filter(and_(Animal.a_age.__lt__(18), Animal.a_age.__gt__(5))).paginate()
return render_template("animal_list.html", pagination=pagination)
使用bootstrap以及flask中自带的pagination在html中写出漂亮的分页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动物列表</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
</head>
<body>
<ul>
{% for item in pagination.items %}
<li>{{ item.a_name }}:{{ item.a_age }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if pagination.has_prev %}
<li>
<a href="/animals/?per_page=3&page={{ pagination.prev_num }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{%- for page in pagination.iter_pages() %}
{% if page %}
{% if page != pagination.page %}
<li><a href="/animals/?per_page=3&page={{ page }}">{{ page }}</a></li>
{% else %}
<li class="active"><a>{{ page }}</a></li>
{% endif %}
{% else %}
<span class=ellipsis>…</span>
{% endif %}
{%- endfor %}
{% if pagination.has_next %}
<li>
<a href="/animals/?per_page=3&page={{ pagination.next_num }}" 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>
</body>
</html>
钩子函数也是flask中间件:
- Django中的中间件
- AOP(面向切面编程)
- before_request
- after_request
@app.route('/animals/')
def animals():
print("处理中")
pagination = Animal.query.filter(and_(Animal.a_age.__lt__(18), Animal.a_age.__gt__(5))).paginate()
return render_template("animal_list.html", pagination=pagination)
@app.before_request
def before():
print("请求前")
@app.after_request
def after(resp):
print("请求结束")
return resp
@app.before_request是请求之前的路由
@app.after_request是请求之后的路由,返回response
在创建数据库表的时候我们会有一类东西可能会涉及到继承比如:
class Dog(db.Model):
__abstract__ = True
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
d_name = db.Column(db.String(16))
class BlackDog(Dog):
b_price = db.Column(db.Float, default=1)
class WhiteDog(Dog):
w_price = db.Column(db.Float, default=2)
如果不加 abstract 抽象属性的话只会产生一个表,那样创建的对象会有很多的空值,这样全部都会成为费数据
给父模型加上下面的属性:
abstract = True
抽象的模型不会产生表映射
子模型会获取父表中的所有字段
Flask四大内置对象
- request
- session
- g
- 全局对象
- 可以用来传递数据
- 做数据载体,容器
- config (app)
- 配置
- 整个app的配置
- key-value