Flask的闪现(message) 请求扩展 中间件 蓝图
補充:一個編程思路
需求:做一些郵件短信微信的消息通知,比如賬單告警之類的;比如數據庫操作,數據庫種類繁多;緩存的選擇比如redis/memcache,諸如此類需要進行選擇配置,如果我們單純的用函數去實現就要進行判斷,選擇越多判斷就要越多,顯然這種寫法是不行的,那么由此我們就想到了django的中間件的配置,只需要在配置文件中寫上路徑就可以了,還有restframework中我們只要在配置文件中寫上一些的組件的路徑或者名稱就可以使用了,我們就可以用這種思路來解決開始的問題
總的流程:我們可以把不同邏輯的處理寫成類放在一個包里,把這些類的路徑放在配置文件中,在全局文件中引入這個包就會執行這個包的_ _init_ _方法,在init方法中去循環配置文件保存類的值,再進行rsplit根據句點符,就得出了路徑個類名,在利用importlib的import_module方法和getattr就得到了類
from s7day140 import settings import importlib """ 配置文件中: MSG_LIST = ["utils.message.email.Email","utils.message.msg.Msg","utils.message.wechat.WeChat", ] """ def send_msgs(msg):for path in settings.MSG_LIST:# m就是路徑,c就是類名m,c = path.rsplit('.',maxsplit=1)# md就是路徑對應的py文件(模塊)md = importlib.import_module(m)# getattr就拿到了模塊中類,然后就可以實例對象了obj = getattr(md,c)()obj.send(msg)?
?
補充:
1、request.query_string ?輸出的是字節類型,如果有報錯的話就用request.args.get(key)
2、request.url就是代表折請求的所有路徑,包括域名和URL數據
類似這樣的:http://127.0.0.1:8000/index/?data=sssss
3、request.path就是只是路由匹配的路徑部分,沒有URL數據
類似這樣的:/index?
?
一、閃現(message)
1、流程:利用flask中的flash,向某個地方設置一個值,可以指定一個分類參數,用的時候就可以從保存的地方取出所有值,可以指定分類參數
2、應用:通常用做對臨時數據的操作
3、原理:message是一個基于Session實現的用于保存數據的集合,保存到用戶對應的session信息中,其特點是:使用一次就刪除利用session.pop方法
一定要注意要加secret_key 參數
from flask import Flask,flash,get_flashed_messages,request,redirect from werkzeug.datastructures import ImmutableMultiDict app = Flask(__name__) app.secret_key = 'asdfasdf'@app.route('/index') def index():val = request.args.get('v')if val == 'oldboy':return 'Hello World!'# 向某個地方設置一個值,category參數是分類的意思flash('超時錯誤',category="x1")return "ssdsdsdfsd"# return redirect('/error') @app.route('/error') def error():"""展示錯誤信息:return:"""# 從某個地方獲取設置過的所有值,并指定分類,并清除。data = get_flashed_messages(category_filter=['x1'])if data:msg = data[0]else:msg = "..."return "錯誤信息:%s" %(msg,)if __name__ == '__main__':app.run()?
?
二、請求擴展
flask中也為我們提供了一些針對請求之前和響應之后執行的裝飾器,以及定制錯誤信息,自定義模版函數和過濾器(flask中不這么叫)的方法
首先實例化對象,做好準備工作:
from flask import Flask,render_template,request,redirect,session,url_for app = Flask(__name__) app.debug = True app.secret_key = 'siuljskdjfs'...... @app.route('/index',methods=['GET'])def index():
print('index函數')
return "Index" if __name__ == '__main__': app.run()
?
1、所有請求進入到視圖會先執行的方法
@app.before_request def process_request1(*args,**kwargs):print('process_request1 進來了')2、所有響應都會經過的方法,必須寫response參數,還要返回response
@app.after_request def process_response1(response):print('process_response1 走了')return response注意注意::
(1)執行順序:before_request按照頁面加載的順序依次執行,after_request按照頁面加載的倒敘依次執行
(2)返回值:
@app.before_request裝飾的方法一般返回None,若有返回值就不會執行視圖了,而是直接從最后一個after_request開始向上執行
after_request要記得返回response
3、只有第一次請求來才會先執行的方法:
可用做一些初始化操作,比如連接數據庫
@app.before_first_request def first(*args,**kwargs):pass?
?
4、定制錯誤信息
# 404是狀態碼,當狀態碼為404時就會調用這個方法 # 可以用來定制一些錯誤顯示頁面和信息 @app.errorhandler(404) # 必須傳一個參數 def error_404(arg):print(arg)# 這個參數的打印結果就是下面的內容,也就是錯誤的提示信息# 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your# spelling and try again.return "404錯誤了"?
5、自定制模版中的函數
注意要加括號
@app.template_global() def sb(a1, a2):return a1 + a2模版中使用:
{{sb(1,2)}}6、自定制模版的過濾器
注意也要加括號
@app.template_filter() def db(a1, a2, a3):return a1 + a2 + a3模版中使用
# 1代表第一個參數,2和3是第二和第三個參數 {{ 1|db(2,3)}}?
?
三、中間件
首先要知道我們利用請求擴展里提供的裝飾器也能夠做一些中間件的事,我們這里說的是根據flask的源碼流程進行自定義方法來實現中間件的操作
具體流程:
app.run會執行werkzeug(第三方WSGI模塊)中的run_simple方法,繼而執行inner方法,繼續執行make_server方法,make_sever方法就會返回一個BaseWSGIServer對象,主要是起socket,當有請求過來時就會觸發flask的call方法,繼而執行wsgi_app方法
利用app.run中的wsgi_app方法可以自定義類,定義的_ _call_ _方法里就可以做一些中間件的事
from flask import Flaskapp = Flask(__name__)@app.route('/') def index():return 'Hello World!'class Md(object):def __init__(self,old_wsgi_app):self.old_wsgi_app = old_wsgi_appdef __call__(self, environ, start_response):print('開始之前')ret = self.old_wsgi_app(environ, start_response)print('結束之后')return retif __name__ == '__main__':app.wsgi_app = Md(app.wsgi_app)app.run()?
四、藍圖blueprint
作用就是構造自己的程序目錄
因為一個項目我們不可能只寫一個py文件,當我們把不同的邏輯處理寫成幾個py文件后,怎么運行,怎么把路由關系建立起來就是個問題,當然我們可以自己寫只要導入其它所有的py文件就可以了但這樣的話一個是繁瑣二是局限性特別大
藍圖就為我們提供了構造程序目錄的方法,下面以一個簡單應用程序為例:
首先我們就要想怎么就能一啟動項目所有的py文件也會跟著執行,這就用到了模塊包的__init__方法,所以我們就想到在init中把所有的py文件都導入,在項目的入口文件中只需要導入這個模塊包就可以了,但是藍圖的思路就是把每個業務的py文件中實例藍圖對象,這個藍圖對象只對當前py文件有效,我們就可以寫路由的對應關系了,在整個業務py文件的包的init文件中實例Flask對象app,把每一個藍圖對象注冊到這個app對象中,這樣所有的路由映射關系就都在app對象里了,在項目的入口文件中只要導入init文件中的app對象,整個流程就可以啟動了
》》目錄結構:
static是靜態文件目錄,默認就叫static,這里的statics是在實例化Flask對象時設置的
templates也是默認的模版文件目錄
views是我們創建的不同業務邏輯的py文件
run.py就是項目的入口
?
》》__init__文件中:
#!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Flask# 參數 # template_folder指定模版文件目錄 # static_folder指定靜態文件目錄 # static_url_path指的是靜態文件的請求url,意思就是必須往這個url發請求 # flask才會去指定的靜態文件目錄中查找 app = Flask(__name__,template_folder='templates',static_folder='statics',static_url_path='/static')from .views.account import account from .views.blog import blog from .views.user import user# 將所有的藍圖對象都注冊到app對象中 app.register_blueprint(account) app.register_blueprint(blog) app.register_blueprint(user)?
》》業務邏輯的py文件,以account.py為例:
#!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Blueprint from flask import render_template from flask import request# 實例化藍圖對象 # 也可以指定當前文件的模版文件目錄,這個目錄別的py文件是無法使用的 account = Blueprint('account', __name__,template_folder='mytemplates')# 建立路由映射關系,只對當前文件有效 @account.route('/login', methods=['GET', "POST"]) def login():return render_template('login.html')?
》》項目的入口run.py
from pro_flaskk import app # 引入init文件中的app對象if __name__ == '__main__':app.run()?
轉載于:https://www.cnblogs.com/wanghl1011/articles/8618225.html
總結
以上是生活随笔為你收集整理的Flask的闪现(message) 请求扩展 中间件 蓝图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 基础 函数
- 下一篇: 3种常用的防盗链的方式