flask之路由詳解


路由簡介

在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,進行處理。處理以后,在拼接到路由。


免責聲明!

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



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