Flask03--路由系統url


02-01 詳解url

1 什么是url?

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

一個URL由以下幾部分組成:

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

2 為什么要有url?

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

 

3 如何應用url?

3.1url和路由的區別

我們調用接口需要調用的是一段具體的代碼,也就是一個python類或者python函數,而url就是對這段代碼的具體映射,也就是說我們可以通過url找到一個具體的python類或者python函數,這便是url。而路由是根據url定位到具體的pyhon類或python函數的程序,這段程序我們稱之為路由。

在Flask程序中使用路由我們稱之為注冊路由,是使用程序實例提供的app.route()裝飾器注冊路由,而括號內的字符串就是url,注冊路由的過程就是完成了 url和python類或函數映射的過程,可以理解為會有一張表保存了url與python類或函數的對應關系。這樣我們以url訪問flask就可以找到對應的程序。

例:

@app.route('/')
def hello_world():
    return 'Hello World!'

按照這種關系我們再寫一個路由

@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.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()函數傳入的動態路由部分由列表轉換成拼接字符串了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM