原文地址:http://www.cnblogs.com/wupeiqi/articles/5341480.htmlhtml
Flask是一個基於Python開發而且依賴jinja2模板和Werkzeug WSGI服務的一個微型框架.前端
Werkzeug本質就是Socket服務端,其用於接收http請求並對請求進行預處理,而後觸發Flask框架,開發人員基於Flask框架提供的功能對請求進行相應的處理,並返回給用戶,若是返回給用戶的內容很複雜,就須要藉助jinja2模板引擎來實現對模板的處理,即:將模板和數據進行渲染,將渲染後的字符串數據返回給用戶瀏覽器。java
「微」(micro) 並不表示你須要把整個 Web 應用塞進單個 Python 文件(雖然確實能夠 ),也不意味着 Flask 在功能上有所欠缺。微框架中的「微」意味着 Flask 旨在保持核心簡單而易於擴展。Flask 不會替你作出太多決策——好比使用何種數據庫。而那些 Flask 所選擇的——好比使用何種模板引擎——則很容易替換。除此以外的一切都由可由你掌握。如此,Flask 能夠與您珠聯璧合。python
默認狀況下,Flask 不包含數據庫抽象層、表單驗證,或是其它任何已有多種庫能夠勝任的功能。然而,Flask 支持用擴展來給應用添加這些功能,如同 Flask 自己實現的同樣。衆多的擴展提供了數據庫集成、表單驗證、上傳處理、各類各樣的開放認證技術等功能。Flask 也許是「微小」的,但它已經準備好在需求繁雜的生產環境中投入使用。程序員
另外的介紹:正則表達式
Flask誕生於2010年,是Armin ronacher(人名)用 Python 語言基於 Werkzeug 工具箱編寫的輕量級Web開發框架。算法
Flask 自己至關於一個內核,其餘幾乎全部的功能都要用到擴展(郵件擴展Flask-Mail,用戶認證Flask-Login,數據庫Flask-SQLAlchemy),都須要用第三方的擴展來實現。好比能夠用 Flask 擴展加入ORM、窗體驗證工具,文件上傳、身份驗證等。Flask 沒有默認使用的數據庫,你能夠選擇 MySQL,也能夠用 NoSQL。數據庫
其 WSGI 工具箱採用 Werkzeug(路由模塊),模板引擎則使用 Jinja2。這兩個也是 Flask 框架的核心。json
Flask經常使用擴展包:flask
安裝:pip install flask
簡單示例:
1 from flask import Flask 2 3 # 建立一個flask的應用程序,名字叫app 4 # flask對象的名字 = Flask(__name__) 5 # app能夠隨意起名字 6 # __name__:表示模塊名 7 8 app = Flask(__name__) 9 10 """ 11 經過裝飾器,設置請求的路由 12 路由:就是一個url的地址,或者在java中也叫作接口 13 語法:@flask對象的名字.route("路徑") 14 注意:app是對象的名字,名字能夠隨意取 15 @app.route('/aaa'):參數必須以/開頭,不然會報錯 ValueError: urls must start with a leading slash 16 def index():def表示定義一個函數,index是函數名字 函數名字隨意取 17 """ 18 @app.route('/') 19 def index(): 20 """寫咱們的業務邏輯""" 21 # return表示展現頁面,渲染頁面,渲染就是展現的意思 22 return "我是第一個flask應用程序" 23 24 25 # 判斷是不是入口 26 # 表示入口函數,固定語法 27 if __name__ == '__main__': 28 # 啓動應用程序 29 app.run()
初始化參數介紹:
1 from flask import Flask 2 3 """ 4 查看參數的快捷鍵:ctrl + p 5 static_path='xxx':靜態路徑,爲了向下兼容,有些低版本使用的是這個 6 static_url_path='xxx':url路徑.表示的也是靜態路徑, 7 表示的是一個意思,目的是爲了向下兼容,表示靜態文件 8 static_folder='static',表示靜態文件夾,系統默認叫static,裏面存放靜態文件,好比圖片等等 9 template_folder='teplates':模板文件夾,裏面存放HTML文件 10 """ 11 app = Flask(__name__, static_path=None, static_url_path=None, static_folder='static',template_folder='templates') 12 13 14 @app.route("/") # 千萬注意:是/ 不是\.是斜槓/ 15 def index(): 16 return "index page" 17 18 19 if __name__ == '__main__': 20 app.run() 21 """ 22 lsof -i 5000:監聽5000端口 23 kill -9 4728: 殺死5000端口的應用PID 24 25 PID是進程id 26 27 加載方式: 28 from_object 對象 29 from_pyfile 文件 30 from_envvar 環境變量 31 """
對象方式加載配置文件:
1 """ 2 起名字不要用中文 3 """ 4 from flask import Flask 5 6 app = Flask(__name__) 7 8 9 class Config(object): 10 """建立一個配置類,名字叫Config,名字隨便取""" 11 # 開啓調試模式,調試模式爲True 12 # 自下而上找錯誤 13 # 加載配置文件的好處:能夠看到具體的錯誤信息,自動定位到錯誤的位置 14 DEBUG = True 15 # 自定義參數,參數不能夠小寫.只能是大寫 16 # 大小寫切換快捷鍵:ctrl + shift +u 17 ITCAST = "python" 18 19 20 # flask程序 從對象加載配置文件,配置文件來自Config這個對象 21 app.config.from_object(Config) 22 23 24 @app.route("/") 25 def index(): 26 # a = 1 / 0 27 # 若是是自定義的參數,就須要本身取 28 # 若是從對象中取自定義的值,必須從對象讀取,不能從文件讀取 29 print(app.config.get('ITCAST')) 30 return 'index page' 31 32 33 if __name__ == '__main__': 34 app.run()
文件方式加載配置文件:
注意:先要在同級目錄下建立一個config.cfg文件
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 6 class Config(object): 7 """建立一個配置類,名字叫Config,名字隨便取""" 8 # 開啓調試模式,調試模式爲True 9 # 自下而上找錯誤 10 # 加載配置文件的好處:能夠看到具體的錯誤信息,自動定位 11 DEBUG = True 12 13 14 # flask程序 從文件加載配置文件 15 # 從對象加載必須 掌握,文件加載也得會 16 # 從對象加載的參數裏面傳入的是對象 17 # 從文件加載的參數裏面傳入的是文件名,是字符串類型,有引號 18 app.config.from_pyfile("config.cfg") 19 20 21 @app.route("/") 22 def index(): 23 a = 1 / 0 24 return 'index page' 25 26 27 if __name__ == '__main__': 28 app.run()
run()參數:
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 6 @app.route('/') 7 def index(): 8 a = 1/0 9 return 'index page' 10 11 12 if __name__ == '__main__': 13 """ 14 修改ip地址: 15 第一個參數是ip地址, 16 第二個是端口號, 17 第三個是開啓調試模式(和以前的DEBUG是同樣的功能, 18 這裏是系統爲了方便寫在這裏的.開發的時候須要本身寫) 19 20 通常不建議修改,就使用這個默認的值就好 21 """ 22 app.run(host='192.168.14.27', port=9000, debug=True)
開啓debug=True模式後,詳細的報錯信息就會展現在控制檯.
路由系統:
經常使用路由系統有以上五種,全部的路由系統都是基於下面的對應關係來處理:
1 #: the default converter mapping for the map. 2 DEFAULT_CONVERTERS = { 3 'default': UnicodeConverter, 4 'string': UnicodeConverter, 5 'any': AnyConverter, 6 'path': PathConverter, 7 'int': IntegerConverter, 8 'float': FloatConverter, 9 'uuid': UUIDConverter, 10 }
自定義轉換器進行正則匹配:
1 """ 2 以前只是限制數據類型,今天限制更多了. 3 限制位數,每一位的數據類型等 4 """ 5 from flask import Flask 6 7 # routing 和路由相關的都在這裏 第一步: 8 from werkzeug.routing import BaseConverter 9 """ 10 轉換器:converter 11 """ 12 13 app = Flask(__name__) 14 15 16 # 須要自定義轉換器,經過正則方式進行自定義轉換器, 17 # alt+enter快捷鍵就是進行導包 第二步:繼承 18 class RegBaseConverter(BaseConverter): 19 # 表示限制的數據類型是數字,而且只能是5位,regex不能隨便取,只能是regex,父類中定義好了 20 regex = '\d{5}' 21 22 23 # app.url_map獲得全部的url地址(也就是路由) 24 # converters 表示轉換器 25 # 自定義轉換器,那麼須要給自定義轉換器起一個名字.注意:本身取的名字不能和系統的重名 26 # 把咱們自定義的轉換器放到converters這個轉換器的集合裏面 第三步:添加到轉換器字典中 27 app.url_map.converters['aaaaaa'] = RegBaseConverter 28 29 30 # 限制數據類型是整型,只能限制數據類型.不能限制參數的位數.很差用. 31 # <aaaaaa:index_id>:進行替換,aaaaaa在這裏就表明上面的正則表達式 第四步:使用 32 @app.route('/index/<aaaaaa:index_id>') 33 def index(index_id): 34 return 'index=%s' % index_id 35 36 37 if __name__ == '__main__': 38 app.run() 39 """ 40 DEFAULT_CONVERTERS = { 41 'default': UnicodeConverter, 42 'string': UnicodeConverter, 43 'any': AnyConverter, 44 'path': PathConverter, 45 'int': IntegerConverter, 46 'float': FloatConverter, 47 'uuid': UUIDConverter, 48 } 49 50 一共6種轉換器,前面兩種是同樣的.默認的是接收全部的和字符型同樣 51 """
更專業的解答:https://segmentfault.com/q/1010000000125259
模板:
一、模板的使用
Flask使用的是Jinja2模板,因此其語法和Django無差異
二、自定義模板方法
Flask中自定義模板方法的方式和Bottle類似,建立一個函數並經過參數的形式傳入render_template,如:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>模板</title> 6 </head> 7 <body> 8 <h1>獲取到後臺傳來的數據:</h1> 9 {# {{ 變量名 }} 表示模板文件的語法,用來獲取後端傳來的變量 #} 10 {# 變量.鍵 的方式獲取鍵對應的值 只要是字典格式的數據,獲取key對應的value 11 都是採用對象/變量 .key的方式 12 #} 13 {#使用p標籤以後,輸出顯示就是一行一行的顯示#} 14 <p>名字:{{ data_obj.name }}</p> 15 <p>年齡{{ data_obj.age }}</p> 16 <p>地址:{{ data_obj.address }}</p> 17 <p>列表數據:{{ data_obj.my_list }}</p> 18 <p>字典中的城市數據:{{ data_obj.my_dict.city }}</p> 19 </body> 20 </html>
對應的後臺.py文件:
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 """ 6 模板傳遞數據: 7 注意: 8 模板實際上是一個包含響應文本的文件. 9 本質就是一個響應的文件.記住:是文件,文件 10 誤區:模板就是HTML. 11 12 做用: 13 1.下降耦合度,更好的控制代碼 14 """ 15 16 17 @app.route('/login') 18 def index(): 19 # 業務邏輯已實現 20 # 處理用戶名,密碼 21 data = { 22 'name': 'libin', 23 'age': 56, 24 'address': 'USA', 25 'my_list': [1, 2, '45'], 26 'my_dict': {'city': 'sz'} 27 } 28 # 第一個參數是模板文件的名字, 29 # 第二個參數是須要傳遞到文件上面的數據,前面參數是佔位符,後面的是變量的名字 30 return render_template('demo1.html', data_obj=data) 31 32 33 if __name__ == '__main__': 34 app.run()
公共組件:
一、請求
對於Http請求,Flask會講請求信息封裝在request中(werkzeug.wrappers.BaseRequest),提供的以下經常使用方法和字段以供使用:
1 request.method 2 request.args 3 request.form 4 request.values 5 request.files 6 request.cookies 7 request.headers 8 request.path 9 request.full_path 10 request.script_root 11 request.url 12 request.base_url 13 request.url_root 14 request.host_url 15 request.host
經常使用的介紹:
args參數:
1 # ------------------------------args參數------------------- 2 """ 3 args:就是get請求時url後面加?的後面的數據 4 """ 5 from flask import Flask, request 6 7 app = Flask(__name__) 8 9 10 @app.route('/index', methods=['GET', 'POST']) 11 def index(): 12 # ?號後面的數據 13 # request.args :獲取到?後面的數據 14 city = request.args.get('city') 15 print(city) 16 return 'index' 17 18 19 if __name__ == '__main__': 20 app.run()
form表單數據:
1 """ 2 request獲取數據 3 """ 4 # -------------------form表單------------------------- 5 from flask import Flask, request 6 7 app = Flask(__name__) 8 9 10 @app.route('/index', methods=['GET', 'POST']) 11 def index(): 12 print('前端請求的url地址:', request.url) 13 """全部的請求數據都是封裝在request裏面""" 14 # request.form:獲取到表單數據 15 # request.form.get():獲取到表單裏面具體的某一個數據 16 name = request.form.get('name') 17 pwd = request.form.get('pwd') 18 return 'name=%s,pwd=%s' % (name, pwd) 19 20 21 if __name__ == '__main__': 22 app.run()
files多媒體數據:
1 # -----------------------files多媒體------------------- 2 from flask import Flask, request 3 4 app = Flask(__name__) 5 6 7 # 上傳圖片,只能選POST方式 8 @app.route('/', methods=['POST']) 9 def index(): 10 # request.files 獲取多媒體數據,好比拿到圖片 11 pic = request.files.get('pic') 12 # pic.save('./bb.png') :保存圖片,上傳圖片 13 pic.save('./bb.png') 14 return '上傳成功!' 15 16 17 if __name__ == '__main__': 18 app.run()
返回JSON格式數據:
from flask import Flask, jsonify app = Flask(__name__) # -------------------就是返回給客戶端呈現的數據是json格式的----------- @app.route('/') def index(): data = { "name": "python", "age": 29 } # -------------jsonify方式------------------------------------------- return jsonify(data) if __name__ == '__main__': app.run()
原生方式返回JSON:
# ------------------------原生方式:json.dumps()---------------------------- from flask import Flask import json app = Flask(__name__) @app.route('/') def index(): data = { "name": "python", "age": 29 } # -------------原生方式json.dumps()-------- # 直接返回報錯,須要進行包裝一下,告訴系統這是個json數據.python默認會識別爲字典 # json.dumps()字典數據轉成json數據 res = json.dumps(data) # 第一個參數表示內容,第二個參數表示狀態碼,第三個表示數據類型 return res, 200, {'Content-Type': 'application/json'} if __name__ == '__main__': app.run()
重定向:
1 """ 2 重定向:請求頁面的時候,請求頁面不存在,返回的是另一個頁面. 3 通常在雙11的活動的時候,活動頁面... 4 京東原來的域名www.360.buy.com,若是訪問原來的就須要跳轉到如今的域名www.jd.com 5 6 """ 7 from flask import Flask, redirect, url_for # redirect, url_for 這兩個是重定向模塊 8 9 app = Flask(__name__) 10 11 12 @app.route('/360buy') 13 def index(): 14 # redirect 重定向 15 """ 16 17 url_for會根據傳入的路由函數名,返回該路由對應的URL,在模板中始終使用url_for()就能夠安全的修改路由綁定的URL,則沒必要擔憂模板中渲染url連接出錯: 18 19 """ 20 return redirect(url_for('jd')) 21 22 23 @app.route('/jd') 24 def jd(): 25 return '進入到京東商城頁面' 26 27 28 if __name__ == '__main__': 29 app.run()
自定義狀態碼:
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 """ 6 自定義狀態碼: 7 使用場景: 8 錯誤代碼的對照表.能夠本身定義相關的錯誤.好比實際開發中的具體錯誤:10004表示註冊成功後未登陸等等 9 10 在交互成功以後要求交互成功的內容再具體一點,是交互的哪些內容成功? 11 """ 12 13 14 @app.route('/') 15 def index(): 16 # 999 是請求狀態碼,是自定義的狀態碼 17 return 'index', 999 # 返回客戶端給用戶看的,999表示...錯誤 18 19 20 if __name__ == '__main__': 21 app.run()
abort異常捕獲:
1 """ 2 abort的做用: 3 1.捕獲HTTP的異常(以前是try...exception抓取),這裏flask從新進行了封裝. 4 2.終止程序 5 3.拋出異常 6 7 細節-注意:在abort(500)函數中和@app.errorhandler(500)中, 8 參數必須是http協議標準的狀態碼. 9 10 abort(狀態碼)和@app.errorhandler(狀態碼)中的參數都是狀態碼,這兩個狀態碼必須一致.即這兩個參數必須一致. 11 12 abort(參數1)和@app.errorhandler(參數2):注意,參數1和參數2必須一致 13 14 15 在開發中實際應用: 16 1.通常用來展現404的頁面(資源沒找到,請求頁面不存在) 17 18 19 """ 20 from flask import Flask, abort 21 22 app = Flask(__name__) 23 24 25 @app.route('/') 26 def index(): 27 name = '' 28 pwd = '' 29 30 if name != 'admin' and pwd != '123': 31 print('進入了函數') 32 # 把程序終止掉,後面的業務邏輯就不須要執行了,由於即便執行也沒有實際意義 33 abort(500) 34 # 進入到數據庫,進行數據庫查詢 35 print('看看我進入數據庫了沒') 36 return 'index page' 37 38 39 @app.errorhandler(500) # 拋出捕獲到的異常信息 40 def error_500_handler(error): 41 # return '程序報錯了:%s' % error 42 return '替換爲一個html頁面' 43 44 45 if __name__ == '__main__': 46 app.run()
內置過濾器filter:
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 """ 6 過濾器本質就是一個函數. 7 做用: 8 1.不只僅只是輸出值 9 2.還但願更改值 10 11 """ 12 13 14 @app.route('/') 15 def index(): 16 return render_template('demo2.html') 17 18 19 if __name__ == '__main__': 20 app.run()
對應的HTML:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>過濾器</title> 6 </head> 7 <body> 8 <h1>過濾器的使用</h1> 9 {#{{ 須要修改的值|過濾器的名字 }}#} 10 {# capitalize: 首字母大寫#} 11 <p>首字母大寫:{{ 'hello'|capitalize }}</p> 12 {# 模板中處於安全考慮,默認狀況下,會把標籤進行轉義,即把<>這個轉成 <> #} 13 {# 可是在 開發中,咱們有時候須要使用標籤展現 ,須要禁止轉義 #} 14 <p>禁止轉義:{{ '<h1>黑馬程序員</h1>'|safe }}</p> 15 <p>單詞大寫:{{ 'hello'|upper }}</p> 16 <p>單詞小寫:{{ 'HELLO'|lower }}</p> 17 <p>單詞反轉:{{ 'hello'|reverse }}</p> 18 <p>每一個單詞的首字母大寫:{{ 'hello world!'|title }}</p> 19 <hr> 20 21 <h1>列表操做:</h1> 22 <p>獲取列表中的第一個元素:{{ [1,2,3,4,5,6]|first }}</p> 23 <p>獲取列表中的最後一個元素:{{ [1,2,3,4,5,6]|last }}</p> 24 <p>列表求和:{{ [1,2,3,4,5,6]|sum }}</p> 25 <p>列表排序:{{ [11,21,3,4,5,6]|sort }}</p> 26 <hr> 27 28 29 30 </body> 31 </html>
自定義過濾器:
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 """ 6 過濾器本質就是一個函數. 7 內置的沒法知足需求 8 自定義過濾器實際上就是寫自定義函數 9 10 app.add_template_filter(do_setup2, 'xx'): 11 1.先定義一個函數 12 2.添加函數名do_setup2到flask的app對象裏面,把過濾器函數名字'xx'傳給模板文件 13 3.在模板文件中取出過濾器函數名字 'xx' 14 15 注意:在模板中只是使用過濾器,並不能自定義過濾器,自定義是在.py文件中進行 16 """ 17 18 19 # pycharm原生格式化代碼:ctrl + alt + l 20 # 目前本身使用的:shift + alt + f 21 22 @app.route('/') 23 def index(): 24 return render_template('demo3.html') 25 26 27 # 自定義filter,每隔一個切割一次 28 def do_setup2(my_list): 29 # my_list是前端傳來的數據 [11,21,3,4,5,6,9] 30 return my_list[::2] 31 32 33 # 在模板裏面添加一個過濾器 34 # 第一個參數:表示自定義函數的名字, 35 # 第二個參數:表示在模板裏面使用的過濾器的名字 36 app.add_template_filter(do_setup2, 'xx') 37 38 if __name__ == '__main__': 39 app.run()
對應的HTML:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>自定義filter</title> 6 </head> 7 <body> 8 {#{{ xx:自定義 }}#} 9 <p>對列表進行切片:{{ [11,21,3,4,5,6,9]|xx }}</p> 10 </body> 11 </html>
控制代碼塊:
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 """ 6 控制代碼塊主要包含兩個: 7 - if/else if /else / endif 8 - for / endfor 9 """ 10 11 12 @app.route('/') 13 def index(): 14 my_list = [ 15 { 16 "id": 1, 17 "value": "我愛工做" 18 }, 19 { 20 "id": 2, 21 "value": "工做令人快樂" 22 }, 23 { 24 "id": 3, 25 "value": "沉迷於工做沒法自拔" 26 }, 27 { 28 "id": 4, 29 "value": "日漸消瘦" 30 }, 31 { 32 "id": 5, 33 "value": "以夢爲馬,越騎越傻" 34 } 35 ] 36 return render_template('demo4.html', my_list=my_list) 37 38 39 if __name__ == '__main__': 40 app.run(debug=True)
對應的HTML:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>控制代碼塊</title> 6 </head> 7 <body> 8 <h1>控制語句</h1> 9 {# 專門給for循環使用 loop.....#} 10 {% for item in my_list %} 11 {% if loop.index==1 %} 12 <li style="background-color: deeppink">{{ item.value }}</li> 13 {% elif loop.index==2 %} 14 <li style="background-color:greenyellow">{{ item.value }}</li> 15 {# 注意: else loop.index==3 這樣是錯誤的寫法,jinja2模板語法會報錯: jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'loop' 16 正確寫法: {% else %} else就是表示最後一個了,再也不須要加loop.index進行判斷 17 #} 18 {% else %} 19 <li style="background-color:red">{{ item.value }}</li> 20 {% endif %} 21 {% endfor %} 22 23 24 </body> 25 </html>
發送消息flash:
1 from flask import Flask, flash, render_template 2 3 """ 4 flash:做用:表示發送消息,往隊列裏面發送 5 flash是閃電的意思 6 7 相似前端裏面的提示消息 8 9 使用場景: 10 在頁面須要展現後端發送過來的消息的時候,進行使用,提示用戶 11 12 13 擴展: 14 1.由於在發送消息的時候使用session,會存儲一些隱私數據,好比購物車,爲了安全起見, 15 在flask中若是使用到session,都必須加密,使用secret_key進行加密 16 """ 17 18 app = Flask(__name__) 19 20 # 加密口令,config['SECRET_KEY'] 注意:config裏面的key必須大寫 21 # ['SECRET_KEY'] 必須遵循config配置文件中默認的寫法 22 # RuntimeError: the session is unavailable because no secret key was set. 23 # Set the secret_key on the application to something unique and secret. 24 # 設置祕鑰不能爲空,不然報錯 25 # app.config['SECRET_KEY'] = '' 26 # 專業術語叫salt加鹽 27 app.config['SECRET_KEY'] = 'shdfsjk' 28 29 # 加密以後再加密,再加密,至少十幾回。銀行密碼6位數字的狀況下。 30 # 專業術語叫作:加鹽salt 加密 31 """ 32 經常使用的加密算法:MD5,SHA1,BASE64等等 33 注意:MD5是不可逆的,即MD5加密以後,不會反向破解出來 34 35 撞庫: 36 37 """ 38 39 40 @app.route('/') 41 def index(): 42 # 內置對象,不須要傳遞 43 flash("用戶名不正確") 44 flash("用戶名不正確") 45 flash("用戶名不正確") 46 flash("用戶名不正確") 47 return render_template('demo6.html') 48 49 50 if __name__ == '__main__': 51 app.run(debug=True)
對應的HTML:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 {# get_flashed_messages 這是一個函數地址,加()纔是一個函數,返回值是flashes 9 10 具體做用:Pulls all flashed messages from the session and returns them. 11 #} 12 {% for msg in get_flashed_messages() %} 13 <p>{{ msg }}</p> 14 {% endfor %} 15 16 </body> 17 </html>
message消息:
1 from flask import Flask, flash,render_template, request, get_flashed_messages 2 3 """ 4 get_flashed_messages(): 5 6 message是一個基於Session實現的用於保存數據的集合,其特色是:使用一次就刪除 7 用來存放臨時值 8 """ 9 app = Flask(__name__) 10 app.secret_key = 'some_secret' 11 12 13 @app.route('/') 14 def index1(): 15 # 12.獲取消息 16 v = get_flashed_messages() 17 print(v) 18 return render_template('index1.html') 19 20 21 # 設置完以後,只能經過瀏覽器訪問一次剛剛設置的值,訪問完以後就不能再第二次訪問了 22 @app.route('/set') 23 def index2(): 24 v = request.args.get('p') 25 # 設置設置消息 26 flash(v) 27 return 'ok' 28 29 30 if __name__ == "__main__": 31 app.run()
對應的HTML:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <h1>這是index1頁面</h1> 9 {% with messages = get_flashed_messages() %} 10 {% if messages %} 11 <ul class=flashes> 12 {% for message in messages %} 13 <li>{{ message }}</li> 14 {% endfor %} 15 </ul> 16 {% endif %} 17 {% endwith %} 18 </body> 19 </html>
模板繼承:
1 from flask import Flask,render_template 2 3 """ 4 模板繼承:複用 5 6 若是子類須要繼承父類,就在父類加一個block 7 8 {% block content %} 9 10 {% endblock %} 11 12 13 子類須要繼承父類: 14 15 {% block content %} 16 <h1>子類的內容</h1> 17 {% endblock %} 18 19 20 須要注意:block裏面的內容,子類和父類必須保證同樣,用來識別是哪個內容被修改 21 22 23 24 在子類中寫{% extends "demo8_father.html" %}, 25 若是子類和父類數據不同,添加block ... 26 """ 27 28 app = Flask(__name__) 29 30 31 @app.route('/') 32 def index(): 33 return render_template('demo7_son.html') 34 35 36 if __name__ == '__main__': 37 app.run()
對應的HTML:
demo7_son:
1 {% extends "demo8_father.html" %} 2 3 {% block content %} 4 <h1>子類的內容頁面</h1> 5 {% endblock %}
demo8_father:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>父類的頂部</h1> 9 10 {% block content %} 11 <h1>父類的內容</h1> 12 {% endblock %} 13 14 <h1>父類的底部</h1> 15 </body> 16 </html>
命令行方式執行程序:
1 from flask import Flask 2 from flask_script import Manager 3 4 # Manager能夠用來管理咱們的應用程序 5 app = Flask(__name__) 6 # 建立一個flask的腳本,傳輸一個flask對象,把app對象交給manager管理 注意:須要傳參數app 7 manager = Manager(app) 8 """ 9 由於公司裏面都是腳本命令行操做 10 """ 11 12 13 @app.route('/') 14 def index(): 15 # index是視圖函數 16 return 'index' 17 18 19 if __name__ == '__main__': 20 manager.run() 21
內置對象:
1 from flask import Flask, render_template, g, url_for 2 3 app = Flask(__name__) 4 5 """ 6 g變量就是一個容器,內置對象,不須要手動傳 7 8 內置對象: 9 做用:若是使用內置對象,就不須要手動傳遞值,直接在頁面上面使用便可 10 只是爲了方便取值. 11 由於在模板頁面裏面已經把這些變量定義好了 12 13 g表示一個容器,裏面能夠存儲值 14 格式: g.變量名 其中變量名能夠隨便取 15 """ 16 17 18 @app.route('/') 19 def index(): 20 g.name = 'heima' 21 return render_template('demo5.html') 22 23 24 if __name__ == '__main__': 25 app.run()
對應的HTML:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>特有內置對象</h1> 9 <p>獲取內置的debug對象:{{ config.DEBUG }}</p> 10 <p>獲取內置的請求的url:{{ request.url }}</p> 11 <p>獲取內置的url_for對象:{{ url_for.url }}</p> 12 <p>獲取內置的g變量裏面的數據:{{ g.name }}</p> 13 </body> 14 </html>
內置的config默認信息: