路由簡介
在flask程序中使用路由,我們稱之為注冊路由,是使用程序實例提供的app.route()裝飾器來注冊路由。
@app.route('/student_list/')
def student_list():
return 'students'
路由的本質及參數
from flask import Flask, url_for, redirect
app = Flask(__name__)
def index(nid):
print(nid, type(nid))
return 'ojbk'
# 指定類型為int或者string類型
app.add_url_rule('/index/<int:nid>', view_func=index, endpoint='index1', methods=['post', 'get'])
# app.route的本質就在執行add_url_rule這個中的rule是路由,endpoint是路由別名,view_func是響應函數
# app.add_url_rule('/index/<int:nid>', view_func=index, methods=['post', 'get'])
@app.route('/login', methods=['get', 'post'])
def login():
# 用endpoint取路由要用url_for 在flask中導入,也就是反向解析
print(url_for("index1"))
return redirect(url_for("index1")) # url_for通過路由的別名反向解析出來路由的url
# 路由參數;methods,可以控制該方法能有哪些請求方式可以訪問
app.add_url_rule("/index", endpoint="index1", view_func=index, methods=["POST", "GET"])
# 路由參數:有名分組,app.add_url_rule("/index/<int:nid>"響應函數必須用nid來接收
if __name__ == '__main__':
app.run()
'''
總結:
1 @app.route("/login") 的本質是app.add_url_rule("/login",view_func=login),所以我們就可以用這兩個方式來添加路由
2 路由的參數,
2.1 endpoint,做是反向解析,如果上面添加路由的時候,沒有傳遞endpoint就是使用響應函數的函數名,反向解析用url_for(),做解析,這個url_for必須在flask里面導入
2.2 methods=["POST","GET"],該參數控制路由允許哪些請求方法訪問,如果不傳,默認只能GET方法
2.3 路由以及路由路由轉化器。"/index/<int:nid>",<參數的類型:用哪個變量來接收>,響應函數中的形參的名字必須轉化器中一致。
'''
動態路由傳參
http://127.0.0.1:5000/student_list/2/
在path中有可變的部分,達到了傳參的目的,我們稱之為動態路由傳參
@app.route('/student_list/<student_id>/')
def student_list(student_id):
return '學生{}號的信息'.format(student_id)
動態路由的過濾
可以對參數限定數據類型,比如限定為student_id必須為整數類型
http://127.0.0.1:5000/student_list/2/
@app.route('/student_list/<int:student_id>/')
def article_detail(student_id):
print(student_id, type(student_id))
return '學生{}號的信息'.format(student_id)
主要有這幾種類型過濾:
string
: 默認的數據類型,接收沒有任何斜杠" /"的字符串
int
: 整型
float
: 浮點型
path
: 和string類型相似,但是接受斜杠,如:可以接受參數/aa/bb/cc/多條放在一起
uuid
: 只接受uuid格式的字符串字符串,
✔提示:uuid為全宇宙唯一的串
上面幾種約束均為如下格式,例子中的int可以換為 string,float,path,uuid
:
@app.route('/student_list/<int:student_id>/')
def article_detail(student_id):
return '學生{}號的信息'.format(student_id)
any
: 可以指定多種路徑,如下面的例子
url_path的變量名是自己定義的
@app.route('/<any(student,class):url_path>/<id>/')
def item(url_path, id):
if url_path == 'student':
return '學生{}詳情'.format(id)
else:
return '班級{}詳情'.format(id)
動態路由的適用場景?
如果想增加網站的曝光率,可以考慮使用動態路由,因為是把path作為參數,搜索引擎的算法會定義你為一個靜態頁面,不會經常改變,有利於搜索引擎的優化。但是如果是公司內部的管理系統就沒有必要使用動態路由,因為內部系統對曝光率沒有要求。
關鍵詞:
- 上面我們接受參數使用的是path(路徑)形式,這種傳參的形式就叫動態路由傳參,有利於搜索引擎的優化。
url_for()的使用
利用視圖函數名字一般不會改變的特性,根據視圖函數的名字去動態精准的獲取url,以便於開發使用。
url_for('視圖函數名字') # 輸出該視圖函數url
具體例子:
from flask import Flask,url_for
app = Flask(__name__)
app.config.update(DEBUG=True)
@app.route('/')
def demo1():
print(url_for("book")) # 注意這個引用的是視圖函數的名字 字符串格式
print(type(url_for("book")))
return url_for("book")
@app.route('/book_list/')
def book():
return 'flask_book'
if __name__ == "__main__":
app.run()
url_for如何處理動態的視圖函數
如果想獲取動態路由,必須以關鍵字實參的形式為動態的path部分賦值,注意動態的path部分必須被賦值,
案例:
@app.route('/demo2/')
def demo2():
student_url = url_for('student', id=5, name='mark') # id 就是動態path的key 必須賦值, # name 將作為查詢字符串傳入
print(student_url)
return student_url
@app.route('/student/<int:id>/')
def student(id):
return 'student {}'.format(id)
控制台輸出:
瀏覽器輸出:
url_for如何為url添加查詢字符串
如果想在路徑后面拼出來查詢字符串,以關鍵字實參的形式放到url_for()里面作為參數,會自動拼成路徑
案例:
@app.route('/demo3/')
def demo3():
school_url = url_for('school', school_level='high', name='college')
# 具體要拼接的查詢參數 以關鍵字實參的形式寫在url_for里
print(school_url)
return school_url
@app.route('/school/')
def school():
return 'school message'
控制台輸出:
瀏覽器輸出:
自定義轉化器(非重點)
# 非重點
#1 寫類,繼承BaseConverter
#2 注冊:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("\d+"):nid>') 正則表達式會當作第二個參數傳遞到類中
from flask import Flask, url_for
from werkzeug.routing import BaseConverter
app = Flask(import_name=__name__)
class RegexConverter(BaseConverter):
"""
自定義URL匹配正則表達式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex
def to_python(self, value):
"""
路由匹配時,匹配成功后傳遞給視圖函數中參數的值
"""
print("to_python",value,type(value))
return int(value)+1
def to_url(self, value):
"""
使用url_for反向生成URL時,傳遞的參數經過該方法處理,返回的值用於生成URL中的參數
"""
val = super(RegexConverter, self).to_url(value)
return val+"222"
# 添加到flask中
app.url_map.converters['regex'] = RegexConverter
# 正則匹配處理結果,要交給to_python,to_python函數可以對匹配處理結果做處理
@app.route('/index/<regex("\d+"):nid>')
def index(nid):
print("index",nid,type(nid))
print(url_for('index', nid='888'))
return 'Index'
if __name__ == '__main__':
app.run()
總結:
1 導入from werkzeug.routing import BaseConverter
2 我寫個繼承BaseConverter。實現3個方法,def __init__ , def to_python , def to_url
3 將上面的類注冊到app.url_map.converters['regex'] = RegexConverter中
4 然后就可以在路由轉化器中使用3中的regex("傳正則")
5 當路由被訪問以后。regex("傳正則")會匹配結果,把結果傳遞to_python,我們可以進行再次處理,to_python處理好的結果,會傳遞給響應函數的形參
6 當用url做反向解析的時候,傳遞給路由轉化器的參數,會經過to_url,進行處理。處理以后,在拼接到路由。