url是統一資源定位符(Uniform Resource Locator的簡寫),對能夠從互聯網上獲得的資源的位置和訪問方法的一種簡潔的表示,是互聯網上標準資源的地址。互聯網上的每一個文件都有一個惟一的URL,它包含的信息指出文件的位置以及瀏覽器應該怎麼處理它。html
一個URL由如下幾部分組成:前端
scheme://host:port/path/?parameter=xxx#anchor https://www.baidu.com/Public/linux/?fr=aladdin#23
顧名思義統一資源定位符,是用來作定位用的,咱們的web開發無非是要調用程序,而調用的具體程序咱們稱之爲python的視圖函數,URL創建了與Python視圖函數一一對應的映射關係,通俗易懂能夠理解爲一條命令觸發了一個python的函數或類。python
咱們調用接口須要調用的是一段具體的代碼,也就是一個python類或者python函數,而url就是對這段代碼的具體映射,也就是說咱們能夠經過url找到一個具體的python類或者python函數,這即是url。而路由是根據url定位到具體的pyhon類或python函數的程序,這段程序咱們稱之爲路由。linux
在Flask程序中使用路由咱們稱之爲註冊路由,是使用程序實例提供的app.route()裝飾器註冊路由,而括號內的字符串就是url,註冊路由的過程就是完成了 url和python類或函數映射的過程,能夠理解爲會有一張表保存了url與python類或函數的對應關係。這樣咱們以url訪問flask就能夠找到對應的程序。web
例:算法
@app.route('/') def hello_world(): return 'Hello World!'
按照這種關係咱們再寫一個路由flask
@app.route('/student_list/') def student_list(): return 'students'
若是你仔細觀察平常所用服務的某些URL格式,會發現不少地址中都包含可變部分。例如,你想根據學生的id找到具體的學生,http://127.0.0.1:5000/student_list/<student_id>/ 仍然在path部分 ,可是你不必寫多個路由,咱們Flask支持這種可變的路由。瀏覽器
見代碼:app
@app.route('/student_list/<student_id>/') def student_list(student_id): return '學生{}號的信息'.format(student_id)
關鍵字:在path中有可變的部分 ,達到了傳參的效果,咱們稱之爲動態路由傳參函數
能夠對參數限定數據類型,好比上面的文章詳情,限定student_id必須爲整數類型
@app.route('/student_list/<int:student_id>/') def article_detail(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做爲參數,搜索引擎的算法會定義你爲一個靜態頁面,不會常常改變,有利於搜索引擎的優化。可是若是是公司內部的管理系統就沒有必要使用動態路由,由於內部系統對曝光率沒有要求。
關鍵詞:
咱們上面介紹了什麼是查詢字符串:
若是咱們在瀏覽器中輸入www.baidu.com/s?wd=python&ad=flask的參數,這個 ?
後的key=value即是查詢字符串,
能夠寫多個key=value用&
相連咱們將查詢字符串做爲參數去請求咱們的flask程序,這即是查詢字符串傳參。
咱們以前再註冊路由的時候會在裏面的path
部分以及函數的形參
設置參數來接受path的參數,咱們在查詢字符串傳參的時候須要從flask
模塊裏面導入request
對象,用request.args
屬性在咱們的程序中根據查詢字符串的key
取出查詢字符串的value
。
args
是request
的一個屬性,其本質是一個Werkzeug
依賴包的的immutableMultiDict
的對象,用於解析咱們傳入的查詢字符串,immutableMultiDict
對象也繼承了Dict
類,因此可使用字典的.get()
方法來獲取,固然了若是咱們有獲取原生未解析的原生查詢字符串的需求,可使用query_string
屬性。
例:
from flask import Flask,request ... @app.route('/student_name/') def school_name_list(): name = request.args.get('name') age = request.args.get('age') return "學生的姓名爲{},年齡爲{}".format(name, age)
咱們在訪問一個網址的時候在調用flask項目的時候須要調用的是一段具體的代碼,也就是一個python類或者python函數,在這裏這個python類咱們稱之爲視圖類,python函數咱們稱之爲視圖函數。
若是咱們在視圖函數中想使用一個url,好比給前端返回,或者咱們在這個視圖函數中返回一個模板文件都會使用到url,url至關於一把鑰匙能夠開啓一些資源。若是你修改了註冊路由編寫的url規則,至關於修改了鑰匙。那麼其餘的視圖函數依舊是使用了原來的鑰匙就無效了,若是項目是一個大項目,你一點點手動的去改涉及到的的url就不合理了。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()
咱們直接訪問http://127.0.0.1:5000/,通過路由的分發會觸發demo1的執行。如圖
若是想獲取動態路由,必須以關鍵字實參的形式爲動態的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()裏面做爲參數,會自動拼成路徑
案例:
@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'
控制檯輸出:
瀏覽器輸出:
咱們能夠經過繼承werkzeug.routing 的BaseConverter
類從而本身定義一個動態路由過濾器的規則
from flask import Flask,request from werkzeug.routing import BaseConverter app = Flask(__name__) app.debug =True class TelephoneConverter(BaseConverter): regex = '1[3857]\d{9}' #右下斜槓d app.url_map.converters['tel'] = TelephoneConverter @app.route('/student/<tel:telenum>/') def student_detail(telenum): return '學生的手機號碼是{}'.format(telenum) if __name__ == '__main__': app.run()
注意:
自定義動態路由過濾器類,該類必須繼承werkzeug.routing
的BaseConverter
類
經過regex
屬性指定路由規則
講自定義的類映射到app.url_map.converters
中(其本質是一個字典)
app.url_map.converters['tel'] = TelephoneConverter
實現效果:
自定義一個類,該經過繼承werkzeug.routing 的BaseConverter
類不光能夠實現正則匹配,咱們介紹一下如下兩個方法:
在該類中實現 to_python 方法:
這個方法的返回值,將會傳遞給視圖函數的形參。咱們能夠利用這個方法實現處理url中動態路由部分。
在該類中實現 to_url 方法:
翻轉url的時候也就是使用url_for函數的時候,咱們傳入指定的動態路由部分,觸發to_url方法,這個方法的返回值,會拼接在非動態路由上,從而實現生成符合要求的url格式。
from flask import Flask,request,url_for from werkzeug.routing import BaseConverter app = Flask(__name__) app.debug =True class ListConverter(BaseConverter): regex = '.*' # 這個regex表明都匹配的意思,能夠根據本身的需求制定url規則 def to_python(self, value): '''這個函數用於拿到了路由裏的動態參數賦值給value, 能夠在to_python進行操做動態參數, 返回操做完的的結果給視圖函數的形參''' return value.split('+') def to_url(self, value): '''這個函數用於和url_for連用, url_for經過指定給動態參數(以關鍵字實參的形式)賦值給value 咱們能夠根據咱們的需求操做url_for傳進來的參數, 而後返回一個理想的動態路由內容拼接在url上''' return '+'.join(value) app.url_map.converters['list'] = ListConverter @app.route('/student_list/<list:students>/') def student_list(students): print(url_for('student_list',students=['a','b'])) # 輸出 /student_list/a+b/ return '{}'.format(students) if __name__ == '__main__': app.run()
證實to_python()
方法把訪問時候動態路由部分被處理成列表了。
證實咱們的 to_url()
方法把url_for()
函數傳入的動態路由部分由列表轉換成拼接字符串了。