Flask03--路由系統url

02-01 詳解url

1 什麼是url?

url是統一資源定位符(Uniform Resource Locator的簡寫),對能夠從互聯網上獲得的資源的位置和訪問方法的一種簡潔的表示,是互聯網上標準資源的地址。互聯網上的每一個文件都有一個惟一的URL,它包含的信息指出文件的位置以及瀏覽器應該怎麼處理它。html

一個URL由如下幾部分組成:前端

scheme://host:port/path/?parameter=xxx#anchor
https://www.baidu.com/Public/linux/?fr=aladdin#23

2 爲何要有url?

顧名思義統一資源定位符,是用來作定位用的,咱們的web開發無非是要調用程序,而調用的具體程序咱們稱之爲python的視圖函數,URL創建了與Python視圖函數一一對應的映射關係,通俗易懂能夠理解爲一條命令觸發了一個python的函數或類。python

 

3 如何應用url?

3.1url和路由的區別

咱們調用接口須要調用的是一段具體的代碼,也就是一個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'

3.2 url傳參的兩種

3.2.1動態路由傳參

若是你仔細觀察平常所用服務的某些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中有可變的部分 ,達到了傳參的效果,咱們稱之爲動態路由傳參函數

3.2.1.1 動態路由的過濾

能夠對參數限定數據類型,好比上面的文章詳情,限定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做爲參數,搜索引擎的算法會定義你爲一個靜態頁面,不會常常改變,有利於搜索引擎的優化。可是若是是公司內部的管理系統就沒有必要使用動態路由,由於內部系統對曝光率沒有要求。

關鍵詞

  • 上面咱們接受參數使用的是path(路徑)形式,這種傳參的形式就叫動態路由傳參,有利於搜索引擎的優化。

3.2.2 查詢字符串傳參

咱們上面介紹了什麼是查詢字符串:

若是咱們在瀏覽器中輸入www.baidu.com/s?wd=python&ad=flask的參數,這個 後的key=value即是查詢字符串,

能夠寫多個key=value用&相連咱們將查詢字符串做爲參數去請求咱們的flask程序,這即是查詢字符串傳參。

咱們以前再註冊路由的時候會在裏面的path部分以及函數的形參設置參數來接受path的參數,咱們在查詢字符串傳參的時候須要從flask模塊裏面導入request對象,用request.args屬性在咱們的程序中根據查詢字符串的key取出查詢字符串的value

argsrequest的一個屬性,其本質是一個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)

3.3 url_for()的使用:

3.3.1簡介視圖函數:

咱們在訪問一個網址的時候在調用flask項目的時候須要調用的是一段具體的代碼,也就是一個python類或者python函數,在這裏這個python類咱們稱之爲視圖類,python函數咱們稱之爲視圖函數。

3.3.2 url_for()的做用:

若是咱們在視圖函數中想使用一個url,好比給前端返回,或者咱們在這個視圖函數中返回一個模板文件都會使用到url,url至關於一把鑰匙能夠開啓一些資源。若是你修改了註冊路由編寫的url規則,至關於修改了鑰匙。那麼其餘的視圖函數依舊是使用了原來的鑰匙就無效了,若是項目是一個大項目,你一點點手動的去改涉及到的的url就不合理了。url_for()就是用來解決這個問題的。

3.3.3url_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的執行。如圖

3.3.4 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)

控制檯輸出:

瀏覽器輸出:

3.3.5 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'

控制檯輸出:

瀏覽器輸出:

3.4 自定義動態路由過濾器

3.4.1 自定義動態路由過濾器之正則匹配

咱們能夠經過繼承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()

注意:

  1. 自定義動態路由過濾器類,該類必須繼承werkzeug.routingBaseConverter

  2. 經過regex屬性指定路由規則

  3. 講自定義的類映射到app.url_map.converters中(其本質是一個字典)

    app.url_map.converters['tel'] = TelephoneConverter

實現效果:

3.4.2 自定義動態路由過濾器之處理動態路由

自定義一個類,該經過繼承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()函數傳入的動態路由部分由列表轉換成拼接字符串了。

相關文章
相關標籤/搜索