路由+視圖
我們之前了解了路由系統是由帶參數的裝飾器完成的。
路由本質:裝飾器和閉包實現的。
路由設置的兩種方式
來看個例子。
@app.route('/index')
def index():
return "index"
我們之前用的裝飾器都是不帶參數的,執行的時候直接是將函數名作為參數傳給裝飾器執行。那么帶參數的裝飾器時如何執行的呢?
我們看一下源碼:先從route點進去。
先去掉@執行

得到這樣的結果。
我們可以將這個帶參數的裝飾器分開執行。
1. 先執行 decorator = app.route('/index')
2. @decorator
將函數名組委參數傳給裝飾器@decorator.

最后我們發現,以上帶參數的裝飾器最后也可以寫成:
def index():
return "index"
app.add_url_rule("/index",None,index)
這就是Flask路由設置的兩種方式。
注意事項:
- 不要讓endpoint重名
- 如果非要重名,必須要保證函數是同一個函數,兩個函數同名也不行。
參數
@app.route和app.add_url_rule參數:
rule, URL規則
view_func, 視圖函數名稱
defaults=None, 默認值,當URL中無參數,函數需要參數時,使用defaults={'k':'v'}為函數提供參數
endpoint=None, 名稱,用於反向生成URL,即: url_for('名稱')
methods=None, 允許的請求方式,如:["GET","POST"]
strict_slashes=None, 對URL最后的 / 符號是否嚴格要求,
如:
@app.route('/index',strict_slashes=False),
訪問 http://www.xx.com/index/ 或 http://www.xx.com/index均可
@app.route('/index',strict_slashes=True)
僅訪問 http://www.xx.com/index
redirect_to=None, 重定向到指定地址
如:
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
或
def func(adapter, nid):
return "/home/888"
@app.route('/index/<int:nid>', redirect_to=func)
subdomain=None, 子域名訪問
from flask import Flask, views, url_for
app = Flask(import_name=__name__)
app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
@app.route("/", subdomain="admin")
def static_index():
"""Flask supports static subdomains
This is available at static.your-domain.tld"""
return "static.your-domain.tld"
@app.route("/dynamic", subdomain="<username>")
def username_index(username):
"""Dynamic subdomains are also supported
Try going to user1.your-domain.tld/dynamic"""
return username + ".your-domain.tld"
if __name__ == '__main__':
app.run()
CBV
通過dispatch_request
import functools
from flask import Flask,views
app = Flask(__name__)
def wrapper(func):
@functools.wraps(func)
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
class UserView(views.MethodView):
methods = ['GET'] #方法
decorators = [wrapper,] #裝飾器
def get(self,*args,**kwargs):
return 'GET'
def post(self,*args,**kwargs):
return 'POST'
app.add_url_rule('/user',None,UserView.as_view('uuuu'))
if __name__ == '__main__':
app.run()
自定義正則
路由管理中沒有正則匹配,但是我們可以自定義正則匹配。
from flask import Flask,url_for
app = Flask(__name__)
# 步驟一:定制類
from werkzeug.routing import BaseConverter
class RegexConverter(BaseConverter):
"""
自定義URL匹配正則表達式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex
def to_python(self, value):
"""
路由匹配時,匹配成功后傳遞給視圖函數中參數的值
:param value:
:return:
"""
return int(value)
def to_url(self, value):
"""
使用url_for反向生成URL時,傳遞的參數經過該方法處理,返回的值用於生成URL中的參數
:param value:
:return:
"""
val = super(RegexConverter, self).to_url(value)
return val
# 步驟二:添加到轉換器
app.url_map.converters['reg'] = RegexConverter
"""
1. 用戶發送請求
2. flask內部進行正則匹配
3. 調用to_python(正則匹配的結果)方法
4. to_python方法的返回值會交給視圖函數的參數
"""
# 步驟三:使用自定義正則
@app.route('/index/<reg("\d+"):nid>')
def index(nid):
print(nid,type(nid))
print(url_for('index',nid=987))
return "index"
if __name__ == '__main__':
app.run()
