Flask框架(七)
flask框架(七)
藍圖
作用:對程序進行目錄結構劃分
不使用藍圖情況下,自己分文件
目錄結構:
-templates
-views
-__init__.py
-user.py
-order.py
-app.py
app.py
from views import app
if __name__ == '__main__':
app.run()
init.py
from flask import Flask,request
app = Flask(__name__)
#不導入這個不行
from . import account
from . import order
from . import user
user.py
from . import app
@app.route('/user')
def user():
return 'user'
order.py
from . import app
@app.route('/order')
def order():
return 'order'
使用藍圖 (Blueprint)
目錄結構:
-app01
-pro
-templates
-__init__.py
-views
-manage.py
manage.py
from pro import app
if __name__ == '__main__':
app.run()
init.py
from flask import Flask
app=Flask(__name__)
from pro import views
app.register_blueprint(views.us)
views.py
from flask import Blueprint,render_template
us=Blueprint("user",__name__)
@us.route("/")
def index():
return render_template("index.html")
總結:
1 xxx = Blueprint('account', name,url_prefix='/xxx') :藍圖URL前綴,表示url的前綴,在該藍圖下所有url都加前綴
2 xxx = Blueprint('account', name,url_prefix='/xxx',template_folder='tpls'):給當前藍圖單獨使用templates,向上查找,當前找不到,會找總templates
3 藍圖的befort_request,對當前藍圖有效
4 大型項目,可以模擬出類似于django中app的概念
請求上下文源碼分析
第一階段:將ctx(request,session)放到Local對象上
第二階段:視圖函數導入:request/session
request.method
-LocalProxy對象.method,執行getattr方法,getattr(self._get_current_object(), name)
-self._get_current_object()返回return self.__local(),self.__local(),在LocakProxy實例化的時候,object.__setattr__(self, '_LocalProxy__local', local),此處local就是:partial(_lookup_req_object, 'request')
-def _lookup_req_object(name):
top = _request_ctx_stack.top #_request_ctx_stack 就是LocalStack()對象,top方法把ctx取出來
if top is None:
raise RuntimeError(_request_ctx_err_msg)
return getattr(top, name)#獲取ctx中的request或session對象
第三階段:請求處理完畢
- 獲取session并保存到cookie
- 將ctx刪除
程序運行,兩個LocalStack()對象,一個里面放request和session,另一個放g和current_app
g對象
專門用來存儲用戶信息的g對象,g的全稱的為global
g對象的特性:
當前請求內你設置就可以取,必須先設置,后取,當前請求可以取無限次。就算你在當前請求設置了g對象,如果不取,其他的請求也取不到。
g對象和session的區別
session對象是可以跨request的,只要session還未失效,不同的request的請求會獲取到同一個session,但是g對象不是,g對象不需要管過期時間,請求一次就g對象就改變了一次,或者重新賦值了一次
代碼示例:
from flask import Flask,g,redirect
app=Flask(__name__)
def set_g():
g.name='sb' #設置g(可以單獨這樣設置,也可以在視圖函數內設置,直接g.屬性名設置)
@app.route("/")
def index():
set_g()
return redirect("/index")
@app.route("/index")
def login():
print(g.name) #獲取g對象
return "2"
if __name__ == '__main__':
app.run()
信號
Flask框架中的信號基于blinker,其主要就是讓開發者可是在flask請求過程中定制一些用戶行為
安裝:pip install blinker
內置信號:
request_started = _signals.signal('request-started') # 請求到來前執行
request_finished = _signals.signal('request-finished') # 請求結束后執行
before_render_template = _signals.signal('before-render-template') # 模板渲染前執行
template_rendered = _signals.signal('template-rendered') # 模板渲染后執行
got_request_exception = _signals.signal('got-request-exception') # 請求執行出現異常時執行
request_tearing_down = _signals.signal('request-tearing-down') # 請求執行完畢后自動執行(無論成功與否)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 應用上下文執行完畢后自動執行(無論成功與否)
appcontext_pushed = _signals.signal('appcontext-pushed') # 應用上下文push時執行
appcontext_popped = _signals.signal('appcontext-popped') # 應用上下文pop時執行
message_flashed = _signals.signal('message-flashed') # 調用flask在其中添加數據時,自動觸發
使用信號:
from flask import Flask,signals
app = Flask(__name__)
#給信號綁定要執行的函數
#無需管調用,因為flask,已經給我們設置調用點
def func(*args,**kwargs):
print('觸發型號',args,kwargs)
#與該信號進行綁定
signals.request_started.connect(func) #綁定信號,請求到來前就會執行綁定的函數
# 觸發信號: signals.request_started.send()
@app.before_first_request
def before_first1(*args,**kwargs):
print("befor_first_request")
@app.before_request
def before_first3(*args,**kwargs):
print("befor_request")
@app.route('/',methods=['GET',"POST"])
def index():
print('視圖')
return "視圖"
一個信號觸發點的流程:(了解知識點)
a. before_first_request
b. 觸發 request_started 信號
c. before_request
d. 模板渲染
渲染前的信號 before_render_template.send(app, template=template, context=context)
rv = template.render(context) # 模板渲染
渲染后的信號 template_rendered.send(app, template=template, context=context)
e. after_request
f. session.save_session()
g. 觸發 request_finished信號
如果上述過程出錯:
觸發錯誤處理信號 got_request_exception.send(self, exception=e)
h. 觸發信號 request_tearing_down
自定義信號(了解)
from flask import Flask
from flask.signals import _signals
app = Flask(import_name=__name__)
# 自定義信號
xxxxx = _signals.signal('xxxxx')
def func(sender,a):
print(sender,a)
print("我是自定義信號")
# 自定義信號中注冊函數
xxxxx.connect(func)
@app.route("/x")
def index():
# 觸發信號
xxxxx.send("sb",a="1") #最少傳遞一個參數
return 'Index'
if __name__ == '__main__':
app.run()
flask-session
作用:將默認保存的簽名cookie中的值 保存到 redis/memcached/file/Mongodb/SQLAlchemy
安裝:pip3 install flask-session
使用1 (復雜的方式)
from flask import Flask,session
from flask_session import RedisSessionInterface
import redis
app = Flask(__name__)
app.secret_key="ajksda"
conn=redis.Redis(host='127.0.0.1',port=6379)
#use_signer設置是否需要secret_key簽名,permanent設置關閉瀏覽器cookie是否失效
app.session_interface=RedisSessionInterface(conn,key_prefix='jason',use_signer=True, permanent=False)
@app.route('/')
def hello_world():
session['sb']='jason'
return 'Hello World!'
@app.route("/index")
def index():
print(session['sb'])
return "ok"
if __name__ == '__main__':
app.run()
使用2 (簡單的方式)
from flask import Flask,session
import redis
from flask_session import Session
app = Flask(__name__)
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] =redis.Redis(host='127.0.0.1',port='6379')
app.config['SESSION_KEY_PREFIX']="jason"
Session(app)
@app.route('/')
def hello_world():
session['sb']='jason'
return 'Hello World!'
@app.route("/index")
def index():
print(session['sb'])
return "ok"
if __name__ == '__main__':
app.run()
總結
以上是生活随笔為你收集整理的Flask框架(七)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常识题(常识问答全集)
- 下一篇: th:标签