HelloWord程序
創建Python項目
- 打開Pycharm,創建 pure Python類型的項目,創建項目完成之后選擇之前創建的py3_flask作為虛擬環境
image.png
第四步路徑可以通過在指定的虛擬環境下,輸入 which python獲得
示例
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
if __name__ == '__main__':
app.run(debug=True)
第一行:導入Flask類
第三行:Flask函數接收一個參數name,他會指向程序所在的包
第六行:裝飾器的作用是將路由映射到試圖函數hello_word
第十一、十二行: Flask應用程序實例的run方法,啟動WEB服務器
在程序運行過程中,程序實例會使用url_map將裝飾器路由和視圖的對應關系保存起來
相關參數配置
在上一節實現了一個最簡單的 Flask 應用程序,只使用了7行代碼,接來對 Flask 程序的創建,運行配置做進一步的了解,具體有:
- Flask 程序初始化參數
- Flask 程序相關配置加載方式
- app.run() 參數
初始化參數
Flask 程序實例在創建的時候,需要默認傳入當前 Flask 程序所指定的包(模塊),接下來就來詳細查看一下 Flask 應用程序在創建的時候一些需要我們關注的參數:
- import_name
- Flask程序所在的包(模塊),傳 name 就可以
- 其可以決定 Flask 在訪問靜態文件時查找的路徑
- static_path
- 靜態文件訪問路徑(不推薦使用,使用 static_url_path 代替)
- static_url_path
- 靜態文件訪問路徑,可以不傳,默認為:/ + static_folder
- static_folder
- 靜態文件存儲的文件夾,可以不傳,默認為 static
- template_folder
- 模板文件存儲的文件夾,可以不傳,默認為 templates
程序加載配置
在 Flask 程序運行的時候,可以給 Flask 設置相關配置,比如:配置 Debug 模式,配置數據庫連接地址等等,設置 Flask 配置有以下三種方式:
- 從配置對象中加載(常用)
- app.config.from_object()
- 從配置文件中加載
- app.config.from_pyfile()
- 從環境變量中加載(了解)
- app.config.from_envvar()
使用方式
示例:
from flask import Flask
# 1.自定義項目配置類
class Config(object):
'''flask項目的配置信息,以類屬性的形式羅列即可'''
DEBUG = True
app = Flask(__name__)
# 方式一:使用類的方式加載項目配置信息
# 2.加載配置類
# app.config.from_object(Config)
# 方式二:使用文件鏈接方式加載項目配置信息
# app.config.from_pyfile('config.ini')
# 方式三:使用環境變量方式
app.config.from_envvar('FLASKCONFIG')
# 常用的項目配置屬性也會在App中保留一份
@app.route('/')
def hello_word():
return 'Hello Word '
if __name__ == '__main__':
app.run()
配置對象
- 從配置對象中加載,創建配置的類,代碼如下:
# 配置對象,里面定義需要給 APP 添加的一系列配置
class Config(object):
DEBUG = True
# 創建 Flask 類的對象,指向程序所在的包的名稱
app = Flask(__name__)
# 從配置對象中加載配置
app.config.from_object(Config)
運行測試,在修改代碼后直接保存,會自動重啟服務器
配置文件
-
創建配置文件 config.ini,在配置文件中添加配置
image.png 使用代碼去加載配置
# 創建 Flask 類的對象,指向程序所在的包的名稱
app = Flask(__name__)
# 從配置文件中加載配置
app.config.from_pyfile('config.ini')
環境變量(了解)
-
編輯運行的相關配置
image.png
image.png
- 使用代碼去加載
# 創建 Flask 類的對象,指向程序所在的包的名稱
app = Flask(__name__)
# 加載指定環境變量名稱所對應的相關配置
app.config.from_envvar('FLASKCONFIG')
讀取配置
- app.config.get()
- 在視圖函數中使用 current_app.config.get()
@app.route('/')
def hello_word():
# 獲取屬性值
print(app.config['DEBUG'])
# 當DEBUG寫錯時,顯示后面的提示信息
print(app.config.get('DEBUG','AA'))
return 'Hello Word '
注:Flask 應用程序將一些常用的配置設置成了應用程序對象的屬性,也可以通過屬性直接設置/獲取某些配置:app.debug = True
路由基本定義
- 明確路由定義的參數,請求方式指定
- PostMan使用
指定路由地址
# 指定訪問路徑為 demo1
@app.route('/demo1')
def demo1():
return 'demo1'
給路由傳參實列
有時我們需要將同一類URL映射到同一個視圖函數處理,比如:使用同一個視圖函數來顯示不同用戶的個人信息
# 路由傳遞參數
@app.route('/user/<user_id>')
def user_info(user_id):
return 'hello %s' % user_id
- 路由傳遞的參數默認當作string處理,也可以指定參數的類型
# 路由傳遞參數
@app.route('/user/<int:user_id>')
def user_info(user_id):
return 'hello %d' % user_id
這里指定int,尖括號中的內容是動態的,在此暫時可以理解為接受int類型的值,實際上int代表使用integerConverter去處理url傳入的參數
指定請求方式
在Flask中,定義一個路由,默認的請求方式為:
- GET
- OPTIONS(自帶)
- HEAD(自帶)
如果想添加請求方式,那么可以如下指定
@app.route('/demo2', methods=['GET', 'POST'])
def demo2():
# 直接從請求中取到請求方式并返回
return request.method
完整代示例:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
# 127.0.0.1/demo1
@app.route('/demo1')
def demo1():
return 'demo1'
# 給路由傳參
# 127.0.0.1:5000/user/str數據類型
# <user_id>轉換器提取url路徑的參數
@app.route('/user/<user_id>')
def demo2(user_id):
return 'user %s' % user_id
# 127.0.0.1:5000/user_int/int數據類型
@app.route('/user_int/<int:user_id>')
def demo3(user_id):
return 'user %d' % user_id
if __name__ == '__main__':
print(app.url_map)
app.run(debug=True)
正則匹配路由
在 web 開發中,可能會出現限制用戶訪問規則的場景,那么這個時候就需要用到正則匹配,根據自己的規則去限定請求參數再進行訪問
具體實現步驟為:
- 導入轉換器基類:在Flask中,所有的路由的匹配規則都是使用轉換器獨享記錄
- 自定義轉換器:自定義類繼承與轉換器基類
- 添加轉換器到默認的轉換器字典中
- 使用自定義轉化器實現自定義匹配規則
代碼實現
- 導入轉換器基類
from werkzeug.routing import BaseConverter
- 自定義轉換器
# 自定義正則轉換器
class RegexConverter(BaseConverter):
def __init__(self, url_map, *args):
super(RegexConverter, self).__init__(url_map)
# 將接受的第1個參數當作匹配規則進行保存
self.regex = args[0]
- 添加轉換器到默認的轉換器字典中,并指定轉換器使用時名字為: re
app = Flask(__name__)
# 將自定義轉換器添加到轉換器字典中,并指定轉換器使用時名字為: re
app.url_map.converters['re'] = RegexConverter
- 使用轉換器去實現自定義匹配規則
- 當前此處定義規則是:3位數字
@app.route('/user/<re("[0-9]{3}"):user_id>')
def user_info(user_id):
return "user_id 為 %s" % user_id
運行測試:http://127.0.0.1:5000/user/123 ,如果訪問的url不符合規則,會提示找不到頁面
系統自帶轉換器
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
系統自帶的轉換器具體使用方式在每種轉換器的注釋代碼中有寫,請留意每種轉換器初始化的參數。
完整代碼示例
from flask import Flask
# 導入轉換器基類
from werkzeug.routing import BaseConverter
app = Flask(__name__)
# 1.自定義轉換器類
class RegexConverter(BaseConverter):
# 重寫regex屬性,當你將正則表達式傳入給他的時候,BaseConVerter類處理
def __init__(self, url_map, re):
# 1.初始化父類的init方法,完成正則定義注冊工作
super(RegexConverter, self).__init__(url_map)
# 2.初始化子類的init方法
self.regex = re
# 2.注冊正則匹配類
app.url_map.converters['re'] = RegexConverter
@app.route('/')
def hello_word():
return 'Hello Word'
# 127.0.0.1:5000/user/123456
# 3.使用自定義正則轉換器
@app.route('/user/<re("[0-9]{6}"):user_id>')
def demo1(user_id):
return 'user %s' % user_id
if __name__ == '__main__':
app.run(debug=True)
獲取請求參數
- request:flask中代表當前請求的 request 對象
- 作用:在視圖函數中取出本次請求數據
- 導入:from flask import request
常用屬性如下:
屬性 | 說明 | 類型 |
---|---|---|
data | 記錄請求的數據,并轉換為字符 | * |
form | 記錄請求中的表單數據 | MultiDict |
args | 記錄請求中的查詢參數 | MultiDict |
cookies | 記錄請求中的cookie信息 | Dict |
headers | 記錄請求中的報文頭 | EnvironHeaders |
method | 記錄請求使用的HTTP方法 | GET/POST |
url | 記錄請求的URL地址 | string |
files | 記錄請求上傳的文件 | * |
完整代碼
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
'''
get: 獲取服務器數據,問號后面攜帶的參數,告知服務器獲取的數據
post: 往服務器新增數據,請求體里面攜帶的參數:一般是需要存到數據庫的數據
'''
# 127.0.0.1:5000/get?user_name=curry&age=18
@app.route('/get')
def demo1():
"""提取get請求問號后面攜帶的參數"""
# request.method 獲取訪問方式:后面字符串必須大寫
if request.method == 'GET':
# 方式: request.method.args.get('key',"")
user_name = request.args.get('user_name', '')
age = request.args.get('age', '')
return '%s %s' % (user_name, age)
else:
return '405請求方式不正確'
@app.route('/post', methods=['post'])
def demo2():
'''提取post請求體中攜帶的參數'''
if request.method == 'POST':
# 方式
user_name = request.form.get('user_name', '')
user_id = request.form.get('user_id', '')
return '%s %s' % (user_name, user_id)
else:
return '405請求方式不正確'
@app.route('/upload', methods=['post'])
def demo3():
if request.method == 'POST':
# 方式:request.files.get('key', '')
file = request.files.get('pic', '')
file.save('./1.jpg')
return 'upload succes'
else:
return '405請求方式不正確'
if __name__ == '__main__':
app.run(debug=True)
構造響應數據
視圖常用邏輯
- 返回JSON
- 重定向
- Url_for
- 自定義狀態碼
返回JSON
在使用Flask寫一個接口時候需要給客戶端返回JSON數據,在Flask中可以直接使用jsonify生成一個JSON的響應
# 返回JSON
@app.route('/demo3')
def demo3():
json_dict = {
"user_id": 10,
"user_name": "laowang"
}
return jsonify(json_dict)
不推薦使用json.dumps轉成JSON字符串直接返回,因為返回的數據要符合HTTP協議規范,如果是JSON需要指定content-type:application/json
完整代碼:
from flask import Flask, jsonify
import json
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
@app.route('/json')
def demo1():
'''json數據轉換'''
dict = {
'name': 'james',
'age': 34,
'info': {
'team': 'laker'
}
}
# 序列化: 將python對象轉換成json字符串
json_str = json.dumps(dict)
# 反序列化: 將json字符串轉換成python對象
my_json = json.loads(json_str)
# 1.能將python對象轉換成json字符串
# 2.能將相應體數封裝成響應對象并返回
# 3.指明了響應數據格式: ContentType = 'application/json'
my_jsons = jsonify(dict)
return my_jsons
# return json_str
if __name__ == '__main__':
app.run(debug=True)
重定向
- 重定向到百度
# 重定向
@app.route('/demo4')
def demo4():
return redirect('http://www.baidu.com')
- 重定向到自己寫的視圖函數
- 可以直接填寫自己的Url路徑
- 也可以使用url_for生成指定試圖函數所對應的url
@app.route('/demo1')
def demo1():
return 'demo1'
# 重定向
@app.route('/demo4')
def demo4():
return redirect(url_for('demo1'))
- 重定向到帶有參數的視圖函數
- 在url_for函數中傳入參數
# 路由傳遞參數
@app.route('/user/<user_id>')
def user_info(user_id):
return 'hello %d' % user_id
# 重定向
@app.route('/demo4')
def demo4():
# 使用 url_for 生成指定視圖函數所對應的 url
return redirect(url_for('user_info', user_id=100))
完整代碼:
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/index')
def hello_word():
return 'Hello Word'
@app.route('/redirect')
def redirects():
'''重定向到百度'''
# 使用redirect方法進行重定向
return redirect('http://www.baidu.com')
@app.route('/demo2')
def demo2():
'''重定向到自身的根路徑'''
# url_for : url反向解析函數
# 根據函數名稱一一解析出對應的url
return redirect(url_for('hello_word'))
if __name__ == '__main__':
app.run(debug=True)
自定義狀態碼
- 在Flask中,可以很方便的返回自定義狀態碼,以實現不符合http協議的狀態碼,例如: status code:666
@app.route('/demo4')
def demo4():
return '狀態碼為 666', 666
裝飾器路由具體實現梳理
- Flask有兩大核心:Werkzeug和Jinja2
- Werkzeug實現路由\調試和web服務器網關接口
- Jinja2實現了模板
- Werkzeug是一個遵循WSGI協議的python函數庫
- 其內部實現了很多Web框架底層的東西,比如request和response對象;
- 與WSGI規范的兼容;支持Unicode;
- 支持基本的會話管理和簽名Cookie;
- 集成URL請求路由等。
- Werkzeug庫的 routing 模塊負責實現 URL 解析。不同的 URL 對應不同的視圖函數,routing模塊會對請求信息的URL進行解析,匹配到URL對應的視圖函數,執行該函數以此生成一個響應信息。
routing模塊內部有: - Rule類
- 用來構造不同的URL模式的對象,路由URL規則
- Map類
- 存儲所有的URL規則和一些配置參數
- BaseConverter的子類
- 負責定義匹配規則
- MapAdapter類
- 負責協調Rule做具體的匹配的工作
狀態保持
- 因為http是一種無狀態協議,瀏覽器請求服務器是無狀態的。
- 無狀態:指一次用戶請求時,瀏覽器\服務器無法知道之前這個用戶做過什么,每次請求都是新的請求
- 無狀態原因:瀏覽器與服務器之間是使用socket套接字進行通信,服務器將請求結果返回給瀏覽器之后,會關閉當前的socket連接,而且服務器也會在處理頁面完畢之后銷毀頁面對象
- 有時需要保持下來用戶瀏覽的狀態,比如用戶是否登陸過,瀏覽過哪些商品等
- 實現狀態保存主要有兩種方式
- 在客戶端保存用cookie
- 在服務端保存用session
無狀態協議
1.協議對于事務處理沒有記憶能力
2.對同一個 url 請求沒有上下文關系
3.每次的請求都是獨立的,它的執行情況和結果與前面的請求和之后的請求是無直接關系的,它不會受前面的請求應答情況直接影響,也不會直接影響后面的請求應答情況
4.服務器中沒有保存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求服務器
5.人生若只如初見
Cookie
-
Cookie:指某些網站為了辨別用戶身份、進行會話跟蹤而儲存在用戶本地的數據(通常經過加密)。
- 復數形式Cookies.
- Cookie是由服務器端生成,發送給客戶端瀏覽器,瀏覽器會將Cookie的key/value保存,下次請求同一網站時就發送該Cookie給服務器(前提是瀏覽器設置為啟用cookie)。
- Cookie的key/value可以由服務器端自己定義。
-
提示:
- Cookie是存儲在瀏覽器中的一段純文本信息,建議不要存儲敏感信息如密碼,因為電腦上的瀏覽器可能被其它人使用
-Cookie基于域名安全,不同域名的Cookie是不能互相訪問的- 如訪問itcast.cn時向瀏覽器中寫了Cookie信息,使用同一瀏覽器訪問baidu.com時,無法訪問到itcast.cn寫的Cookie信息
- 瀏覽器的同源策略
- 當瀏覽器請求某網站時,會將本網站下所有Cookie信息提交給服務器,所以在request中可以讀取Cookie信息
- Cookie是存儲在瀏覽器中的一段純文本信息,建議不要存儲敏感信息如密碼,因為電腦上的瀏覽器可能被其它人使用
設置cookie
from flask imoprt Flask,make_response
@app.route('/cookie')
def set_cookie():
resp = make_response('this is to set cookie')
resp.set_cookie('username', 'itcast')
return resp
設置過期時間
@app.route('/cookie')
def set_cookie():
response = make_response('hello world')
response.set_cookie('username', 'itheima', max_age=3600)
return response
獲取cookie
from flask import Flask,request
#獲取cookie
@app.route('/request')
def resp_cookie():
resp = request.cookies.get('username')
return resp
完整代碼:
from flask import Flask, make_response, request
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
@app.route('/login')
def login():
'''登錄成功后借助cookie保存登錄信息'''
# 1.創建響應對象
response = make_response('login success')
# 2.借助響應對象的set_cookie方法設置鍵值對
'''
參數1: key 參數2: value 參數3: max_age = 表示過期時長
'''
response.set_cookie('user_name', 'laowang', max_age=3600)
response.set_cookie('user_id', '1', max_age=3600)
return response
@app.route('/index')
def index():
'''再次請求首頁的時候,提起cookie中的用戶信息'''
user_name = request.cookies.get('user_name', '')
user_id = request.cookies.get('user_id', '')
return 'index %s -- %s' % (user_name, user_id)
@app.route('/login_out')
def loginout():
'''退出登錄刪除cookie中用戶數據'''
# 1.構建響應對象
respone = make_response('login out delete')
# 2.利用響應對象中的delete_cookie方法刪除對應的cookie
respone.delete_cookie('user_name')
respone.delete_cookie('user_id')
return respone
if __name__ == '__main__':
app.run(debug=True)
Session
- 對于敏感、重要的信息,建議要存儲在服務器端,不能存儲在瀏覽器中,如用戶名、余額、等級、驗證碼等信息
- 在服務器端進行狀態保持的方案就是Session
- Session依賴于Cookie
session數據的獲取
session:請求上下文對象,用于處理HTTP請求中的一些數據內容
@app.route('/set_session')
def set_session():
session['username'] = 'itcast'
return 'set_session ok!'
@app.route('/get_session')
def get_session():
return session.get('username')
記得設置secret_key: app.secret_key = 'password' 的作用
https://segmentfault.com/q/1010000007295395
完整代碼:
from flask import Flask, session
app = Flask(__name__)
# 加密
app.secret_key = 'asdfghjkl'
@app.route('/')
def hello_word():
return 'Hello Word'
@app.route('/login')
def login():
'''登錄成功借助cookie儲存用戶登錄信息到服務器'''
# session 會將用戶數據存儲到服務器中,一般是數據庫
session['user_name'] = 'laosong'
session['user_id'] = '1'
return 'login sucess'
@app.route('/index')
def index():
'''再次請求首頁的時候可以借助session提取用戶的登錄信息'''
user_name = session.get('user_name')
user_id = session.get('user_id')
return 'user_name : %s, user_id : %s' % (user_name, user_id)
@app.route('/out')
def login_out():
'''退出后刪除'''
session.pop('user_name', '')
session.pop('user_id', '')
return 'out susser'
if __name__ == '__main__':
app.run(debug=True)
請求鉤子
在客戶端和服務器交互的過程中,有些準備工作或掃尾工作需要處理,比如:
- 在請求開始時,建立數據庫連接;
- 在請求開始時,根據需求進行權限校驗;
- 在請求結束時,指定數據的交互格式;
為了讓每個視圖函數避免編寫重復功能的代碼,Flask提供了通用設施的功能,即請求鉤子。
請求鉤子是通過裝飾器的形式實現,Flask支持如下四種請求鉤子:
- before_first_request
- 在處理第一個請求前執行
- before_request
- 在每次請求前執行
- 如果在某修飾的函數中返回了一個響應,視圖函數將不再被調用
- after_request
- 如果沒有拋出錯誤,在每次請求后執行
- 接受一個參數:視圖函數作出的響應
- 在此函數中可以對響應值在返回之前做最后一步修改處理
- 需要將參數中的響應在此參數中進行返回
- teardown_request:
- 在每次請求后執行
- 接受一個參數:錯誤信息,如果有相關錯誤拋出
完整代碼:
from flask import Flask
from flask import abort
app = Flask(__name__)
# 在第一次請求之前調用,可以在此方法內部做一些初始化操作
@app.before_first_request
def before_first_request():
print("before_first_request")
# 在每一次請求之前調用,這時候已經有請求了,可能在這個方法里面做請求的校驗
# 如果請求的校驗不成功,可以直接在此方法中進行響應,直接return之后那么就不會執行視圖函數
@app.before_request
def before_request():
print("before_request")
# if 請求不符合條件:
# return "laowang"
# 在執行完視圖函數之后會調用,并且會把視圖函數所生成的響應傳入,可以在此方法中對響應做最后一步統一的處理
@app.after_request
def after_request(response):
print("after_request")
response.headers["Content-Type"] = "application/json"
return response
# 請每一次請求之后都會調用,會接受一個參數,參數是服務器出現的錯誤信息
@app.teardown_request
def teardown_request(e):
print("teardown_request")
@app.route('/')
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
- 在第一次請求時打印
before_first_request
before_request
after_request
teardown_request
- 在第二次請求時打印
before_request
after_request
teardown_request
異常捕獲
HTTP異常主動拋出
- abort 方法
- 拋出一個給定狀態的HTTPException 或者 指定響應, 例如想要用一個頁面未找到異常來終止請求,可以調用abort(404)
- 參數
- code-HTTP的錯誤狀態碼(必須)
# abort(404)
abort(500)
拋出狀態碼的話,只能拋出 HTTP 協議的錯誤狀態碼
捕獲錯誤
- errorhandler裝飾器
- 注冊一個錯誤處理程序,當程序拋出指定錯誤狀態碼的時候,就會調用該裝飾器所裝飾的方法
- 參數
- code_or_exception-HTTP的錯誤狀態碼或指定異常
- 例如統一處理狀態碼為500的錯誤給用戶友好提示:
@app.errorhandler(500)
def internal_server_error(e):
return '服務器搬家了'
- 捕獲指定異常
@app.errorhandler(ZeroDivisionError)
def zero_division_error(e):
return '除數不能為0'
完整代碼:
from flask import Flask, redirect, abort
app = Flask(__name__)
@app.route('/')
def hello_word():
# 定義兩個錯誤
# a = 1/0
# abort 指定錯誤
abort(404)
return 'Hello Word'
@app.errorhandler(404)
def handler(e):
'''404'''
print(e)
# 重定向
return redirect('http://hd.mi.com/webfile/zt/hd/2014042802/cn.html')
@app.errorhandler(ZeroDivisionError)
def error(a):
'''捕獲異常'''
return '不能除零'
if __name__ == '__main__':
app.run(debug=True)
上下文
上下文:即語境,語意,在程序中可以理解為在代碼執行到某一時刻時,根據之前代碼所做的操作以及下文即將要執行的邏輯,可以決定在當前時刻下可以使用到的變量,或者可以完成的事情。
Flask中有兩種上下文,請求上下文和應用上下文
Flask中上下文對象:相當于一個容器,保存了 Flask 程序運行過程中的一些信息。
請求上下文(request context)
在 flask 中,可以直接在視圖函數中使用 request 這個對象進行獲取相關數據,而 request 就是請求上下文的對象,保存了當前本次請求的相關數據,請求上下文對象有:request、session
- request
- 封裝了HTTP請求的內容,針對的是http請求。舉例:user = request.args.get('user'),獲取的是get請求的參數。
- session
- 用來記錄請求會話中的信息,針對的是用戶信息。舉例:session['name'] = user.id,可以記錄用戶信息。還可以通過session.get('name')獲取用戶信息。
應用上下文(application context)
它的字面意思是 應用上下文,但它不是一直存在的,它只是request context 中的一個對 app 的代理(人),所謂local proxy。它的作用主要是幫助 request 獲取當前的應用,它是伴 request 而生,隨 request 而滅的。
應用上下文對象有:current_app,g
current_app
應用程序上下文,用于存儲應用程序中的變量,可以通過current_app.name打印當前app的名稱,也可以在current_app中存儲一些變量,例如:
- 應用的啟動腳本是哪個文件,啟動時指定了哪些參數
- 加載了哪些配置文件,導入了哪些配置
- 連了哪個數據庫
- 有哪些public的工具類、常量
- 應用跑再哪個機器上,IP多少,內存多大
current_app.name
current_app.test_value='value'
g變量
g 作為 flask 程序全局的一個臨時變量,充當者中間媒介的作用,我們可以通過它傳遞一些數據,g 保存的是當前請求的全局變量,不同的請求會有不同的全局變量,通過不同的thread id區別
g.name='abc'
不同的請求,會有不同的全局變量
兩者區別:
- 請求上下文:保存了客戶端和服務器交互的數據
- 應用上下文:flask 應用程序運行過程中,保存的一些配置信息,比如程序名、數據庫連接、應用信息等
上下文中的對象只能在指定上下文中使用,超出范圍不能使用 請求上下文和應用上下文原理實現:https://segmentfault.com/a/1190000004223296
完整代碼
from flask import Flask, request, session, current_app, g
app = Flask(__name__)
app.secret_key = 'asdfghjkl'
@app.route('/')
def hello_word():
# 請求上下文
print(request.method)
print(request.url)
session['user_name'] = 'curry'
print(session.get('user_name', ''))
# 應用上下文
current_app.config.get("DEBUG")
g.user = 'James'
print(g.user)
return 'Hello Word'
if __name__ == '__main__':
app.run(debug=True)
Flask-script擴展
通過使用Flask-Script擴展,我們可以在Flask服務器啟動的時候,通過命令行的方式傳入參數。而不僅僅通過app.run()方法中傳參,比如我們可以通過:
python hello.py runserver -host ip地址
以上代碼告訴服務器在哪個網絡接口監聽來自客戶端的連接。默認情況下,服務器只監聽來自服務器所在的計算機發起的連接,即localhost連接。
我們可以通過python hello.py runserver --help來查看參數。
代碼實現
- 安裝Flask-Script
pip install flask-script
- 集成Flask-Script
from flask import Flask
from flask_script import Manager
app = Flask(__name__)
# 把 Manager 類和應用程序實例進行關聯
manager = Manager(app)
@app.route('/')
def index():
return '床前明月光'
if __name__ == "__main__":
manager.run()
Flask-Script 還可以為當前應用程序添加腳本命令,后續項目中會使用到