篩選
查詢數據篩選語法:類名.query.篩選符
.all( ):獲取結果集;.count( ):獲取查詢到的對象數量
類名.query.filter(類名.屬性.運算符('xxx')).all()
類名.query.filter(類名.屬性 數學運算符 值).all()
篩選符:
filter_by():根據什么過濾,通常用在級連關系查詢上,屬性=值。不常用; filter(): 查詢獲取數據
offset(): 偏移,偏移前幾條取數據; limit(): 限制,限制取多少條數據; order_by(): 根據什么字段排序;
get(): 根據主鍵獲取數據; first(): 取第一個元素; 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)返回的對象。包含了所有的分⻚頁信息。
封裝實現:persons = Person.query.paginate(page_num, per_page, False).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: 返回一個迭代器。在分頁導航條上顯示的頁碼列表。顯示不完全時返回NOne
- 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>