筛选
查询数据筛选语法:类名.query.筛选符
.all( ):获取结果集;.count( ):获取查询到的对象数量
类名.query.filter(类名.属性.运算符('xxx')).all()
类名.query.filter(类名.属性 数学运算符 值).all()
筛选符:
filter_by():根据什么过滤,通常用在级连关系查询上,属性=值。不常用; filter(): 查询获取数据
offset(): 偏移,偏移前几条取数据; limit(): 限制,限制取多少条数据; order_by(): 根据什么字段排序;
paginate(): 分页
- 数学运算符:
contains 包含,模糊查询; startswith 以什么开始; endswith 以什么结束;
in_ 在什么范围中; like 包含,模糊查询; __gt__ 大于
__ge__ 大于等于; __lt__ 小于; __le__ 小于等于
1 import random
2 from operator import or_, and_
3 from flask import Flask, render_template, request, redirect, url_for
4 from flask_sqlalchemy import SQLAlchemy
5 from sqlalchemy import text
6
7 app = Flask(__name__)
8 app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///flaskmodel.sqlite"
9 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
10 db = SQLAlchemy(app)
11
12
13 class Student(db.Model):
14 id = db.Column(db.Integer, primary_key=True, autoincrement=True)
15 name = db.Column(db.String(32), unique=True)
16 score = db.Column(db.Integer, default=60)
17 def save(self): # 类方法。对数据进行保存提交
18 db.session.add(self)
19 db.session.commit()
20
21 # 数据库初始化,新建一个数据库
22 @app.route("/init/")
23 def init():
24 db.create_all() # 新建数据库
25 return "初始化成功"
26 # 新建一个学生表,在内加入学生信息
27 @app.route("/addstudent/")
28 def add_student():
29 student = Student(name="小明%d" % random.randrange(10000), score=random.randrange(100))
30 student.save() # 调用save()类方法,对要添加的数据进行添加提交
31 return "添加成功"
32
33
34 @app.route("/students/")
35 def students():
36 # 获取成绩在 80分以上的学生信息
37 student_list = Student.query.filter(Student.score > 80).all()
38 student_list = Student.query.filter(Student.score.__gt__(80)).all()
39
40 # 获取成绩在 60分以下的学生信息
41 student_list = Student.query.filter(Student.score < 60).all()
42 student_list = Student.query.filter(Student.score.__lt__(60)).all()
43
44 # 获取成绩是 [60、81、100、200]列表内的学生信息
45 student_list = Student.query.filter(Student.score.in_([60, 81, 100, 200])).all()
46
47 # 获取成绩在 60分以上、80分一下的学生信息。
48 # filter之后对象类型是BaseQuery,可以链式调用:Student.query.filter(xxx).filter().filter().filter()
49 student_list = Student.query.filter(Student.score > 60).filter(Student.score < 80).all()
50
51
52 # filter_by():通常级联查询,条件是确切的=那种。条件 改成 属性=值
53 student_list = Student.query.filter_by(score = 80).all()
54
55 # offset():越过三条数据取3条数据的 学生数据结果
56 student_list = Student.query.offset(3).limit(3).all()
57
58 # 通过成绩从高到底排序,order_by(text("-score"))
59 student_list = Student.query.order_by(text("-score")).all()
60
61 # 通过order_by对成绩排序,越过前三条数据后offset(3),取四条学生信息数据limit(4)
62 # order_by必须放在最前面。limit和offset无顺序,实际上都是先offset再limit
63 student_list = Student.query.order_by("score").limit(4).offset(3).all()
64
65
66 # BaseQuery是可迭代元素,可以被for..in迭代出元素。all只是将格式转换为了列表。
67 student_list = Student.query.order_by("score")
68
69 # 获取学生数据的第一个元素,结果不再是复数。不可迭代。结果的类型是一个Student对象
70 student = Student.query.first()
71 return render_template("student_list1.html", student_list=student_list)
72
73
74 # 原生分页。可以从客户端接受参数,参数是页码,每一个三条数据
75 page = request.args.get("page", 1, type=int) # 获取get请求数据:参数是page、默认值是1、类型是:int
76 student_list = Student.query.offset(3*(page-1)).limit(3).all()
77 return render_template("student_list1.html", student_list=student_list)
78
79 # 对获取的数据进行分页
80 pagination = Student.query.paginate()
81 return render_template("student_list1.html", pagination=pagination)
82
83
84 if __name__ == '__main__':
85 app.run()
- 逻辑运算符:
与and_ 或or_ 非not_
filter(and_(条件),条件...) filter(or_(条件),条件...) filter(not_(条件),条件...)
# 与:and_ filter(and_(条件))
huochelist = kaihuoche.query.filter(and_(kaihuoche.id == 1,kaihuoche.name == 'lc'))
# 或:or_ filter(or_(条件))
huochelist = kaihuoche.query.filter(or_(kaihuoche.id == 1,kaihuoche.name =='lc'))
# 非:not_ filter(not_(条件)) 注意条件只能有一个
huochelist = kaihuoche.query.filter(not_(kaihuoche.id == 1))
1 # 查询指定范围内的数据。and_ 方法
2 @app.route("/students2/")
3 def students2():
4 student_list = Student.query.filter(and_(Student.score.__gt__(60), Student.score.__lt__(90)))
5 return render_template("student_list2.html", student_list=student_list)
6
7 # 查询后 删除数据
8 @app.route("/dropfirst/")
9 def drop_first():
10 student = Student.query.order_by(text("-score")).first()
11 print(student.score)
12 db.session.delete(student)
13 db.session.commit()
14 return "88"
15
16 # 查询后,修改数据值
17 @app.route("/updatescore/")
18 def update_score():
19 student = Student.query.order_by(text("score")).first()
20 print(student.score, student.id)
21 student.score = 100
22 db.session.add(student)
23 db.session.commit()
24 return "完成"
25
26 if __name__ == '__main__':
27 app.run()
分页
分页器:paginate。分页查询,需要想要的页码,每一页显示多少数据
分页对象:分页器(Pagination)返回的对象。包含了所有的分⻚页信息。
.items
原生实现:persons = Person.query.offset((page_num - 1) * per_page).limit(per_page)
select * from users offset 0 limit 20 ;select * from users offset 20 limit 40
- 使用:pagination(page,per_page, False(是否抛异常))
- page: 当前的⻚页码
- per_page: 每⻚页的条数
- error_out: 当查询出错时是否报错
1 @bp.route('/students/')
2 def student_list():
3 """
4 /students/?page=2
5 """
6 page = int(request.args.get('page', 1))
7 per_page = 2 # 每页显示2条数据
8 students = Student.query.paginate(page=page, per_page=per_page)
9
10 return render_template('students.html', students=students)
- 属性
page:当前⻚页码 pages:总⻚页数 total:总条数
prev_num:上⼀⻚页的⻚页码 next_num: 下⼀⻚页的⻚页码
has_prev: 是否有上一⻚页 has_next: 是否有下一⻚页
items: 当前⻚页的数据 per_page: 每⻚页的条数,默认为20条
1 <div>
2 <a href="{{ url_for('blue.student_list') }}">首页</a>
3
4 {% if students.has_prev %} 是否有上一页
5 <a href="{{ url_for('blue.student_list', page=students.prev_num) }}">上一页</a>
6 {% endif %}
7
8 当前{{ students.page }}页,共{{ students.pages }}页,总共{{ students.total }}条
9
10 {% if students.has_next %} 是否有下一页
11 <a href="{{ url_for('blue.student_list', page=students.next_num) }}">下一页</a>
12 {% endif %}
13
14 <a href="{{ url_for('blue.student_list', page=students.pages) }}">尾页</a>
15 </div>
- 方法
- iter_pages:
- prev:
- next:
1 <div>
2 {% for page in students.iter_pages() %}
3 {% if page %}
4 {% if page == students.page %}
5 {{ page }}
6 {% else %}
7 <a href="{{ url_for('blue.student_list', page=page) }}">{{ page }}</a>
8 {% endif %}
9 {% else %}
10 ...
11 {% endif %}
12 {% endfor %}
13 </div>
- 分页宏定义
{# 分页显示的宏 #}
{% macro pagination_widget(pagination, endpoint) %}
<ul class="pagination">
<li{% if not pagination.has_prev %} class="disabled"{% endif %}>
<a href="{% if pagination.has_prev %}{{ url_for(endpoint,page = pagination.page - 1, **kwargs) }}
{% else %}#{% endif %}">«
</a>
</li>
{% for p in pagination.iter_pages() %}
{% if p %}
{% if p == pagination.page %}
<li class="active">
<a href="{{ url_for(endpoint, page = p, **kwargs) }}">{{ p }}</a>
</li>
{% else %}
<li>
<a href="{{ url_for(endpoint, page = p, **kwargs) }}">{{ p }}</a>
</li>
{% endif %}
{% else %}
<li class="disabled">
<a href="#">…</a>
</li>
{% endif %}
{% endfor %}
<li{% if not pagination.has_next %} class="disabled"{% endif %}>
<a href="{% if pagination.has_next %}{{ url_for(endpoint,page = pagination.page + 1, **kwargs) }}{% else %}#{% endif %}">»</a>
</li>
</ul>
{% endmacro %}
过滤
过滤器:
default:默认值 capitalize:首字母大写 lower:全小写 upper:全大写
trim:去除空格 reverse:反转 format:格式化输出 safe:关闭转义(已审查,没有安全隐患)
striptags:将值中标签去掉 round:四舍五入(截取) abs:绝对值 first:第一个元素
last:最后一个元素 length:列表长度 sum:列表求和 sort:列表排序(升序) join:合并字符串
- 模版文件中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
语法:
{{ 变量 | 过滤器 | 过滤器 }}
例子:
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
<p>{{ name | default('No name') }}</p>
{# 单词首字母大写 #}
<p>{{ 'hello' | capitalize }}</p>
{# 单词全小写 #}
<p>{{ 'XML' | lower }}</p>
{# 去除字符串前后的空白字符 #}
<p>{{ 'hello' | trim }}</p>
{# 字符串反转,返回"olleh" #}
<p>{{ 'hello' | reverse }}</p>
{# 格式化输出,返回"Number is 2" #}
<p>{{ '%s is %d' | format("Number", 2) }}</p>
{# 关闭HTML自动转义 #}
<p>{{ '<em>name</em>' | safe }}</p>
{# 四舍五入取整,返回13.0 #}
<p>{{ 12.8888 | round }}</p>
{# 向下截取到小数点后2位,返回12.88 #}
<p>{{ 12.8888 | round(2, 'floor') }}</p>
{# 绝对值,返回12 #}
<p>{{ -12 | abs }}</p>
{# 取第一个元素 #}
<p>{{ [1,2,3,4,5] | first }}</p>
{# 取最后一个元素 #}
<p>{{ [1,2,3,4,5] | last }}</p>
{# 返回列表长度,可以写为count #}
<p>{{ [1,2,3,4,5] | length }}</p>
{# 列表求和 #}
<p>{{ [1,2,3,4,5] | sum }}</p>
{# 列表排序,默认为升序 #}
<p>{{ [3,2,1,5,4] | sort }}</p>
{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
<p>{{ [1,2,3,4,5] | join(' | ') }}</p>
</body>
</html>
- template_filter
1 @bp.app_template_filter('mycut')
2 def mycut(x):
3 return x if len(x) < 6 else x[:5] + '...'
4 """
5 使用
6 <p>{{ 'hello' | mycut }}</p>
7 """
拾遗
1 # 自定义上下文处理器。context_processor(模板的全局变量)
2 import time
3
4 @app.context_processor
5 def client_ip():
6 return dict(remote_ip=request.remote_addr)
7
8 @app.context_processor
9 def get_current_time():
10 def get_time(fmt="%b %d, %Y - %H:%M:%S"):
11 return time.strftime(fmt)
12 return dict(current_time=get_time)
13
14 # 使用:在任意模板页面都可以是使用 current_time 这个函数
15 <p>Current Time is: {{ current_time() }}</p>
16 <p>Current Day is: {{ current_time("%Y-%m-%d") }}</p>
17
18
19 # ————————————————————————————————————————————————————————————#
20 # 自定义模板过滤器。template_filter
21 @bp.app_template_filter('mycut')
22 def mycut(x):
23 return x if len(x) < 6 else x[:5] + '...'
24
25 # 使用
26 <p>{{ 'hello' | mycut }}</p>
生如逆旅 一苇以航