11.2 Flask 配置文件,路由系統

配置文件系統

構建 Flask 應用時指定

app = Flask(
   __name__,
   template_folder = '',  # 指定存儲模板文件夾名稱
   static_url_path = '',  # 指定靜態文件訪問路徑
   static_folder = '',   # 指定存儲靜態文件的文件夾名稱
)

 

通常不推薦修改此配置. 默認的配置便可python

 

啓動程序時指定運行配置

app.run(
  debug = True,    # 調試模式
  port = 8888      # 端口
  host = '0.0.0.0'  # 指定可以訪問到本項目的ip地址,不設置此的話只能本身和本身玩
)

 

 

自定義配置文件

建立一個 setting.py 用於存放配置文件的相關屬性正則表達式

配置文件中能夠進行分級繼承來區分不一樣視圖的配置文件設置json

默認配置文件放在項目根路徑下flask

# settings.py
    
    class Base(object):    # 全部的都要有用到的配置更改 
        TEST = True

    class Dev(Base):
        DEV = True

    class Pro(Base):
        PRO = True 

配置文件的設置方式

經常使用的是如下三種session

# 方式1 直接更改
app.config["要更改的字段"] = True  
 
# 方式2 指定對象方式 # app.config.from_object("settings.Dev") # 經過另外指定配置文件來保存更改 app.config.from_object("settings.Pro") # 能夠指定多套配置文件隨意切換

# 方式3 指定文件方式
app.config.from_pyfile("settings.py") # 經過配置文件名來
# PS: 從sys.path中已經存在路徑開始寫
 

默認的配置文件

flask中的配置文件是一個flask.config.Config對象(繼承字典),默認的配置以下閉包

   'DEBUG':                                get_debug_flag(default=False),  是否開啓Debug模式
    'TESTING':                              False,                          是否開啓測試模式
    'PROPAGATE_EXCEPTIONS':                 None,                          
    'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
    'SECRET_KEY':                           None,
    'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
    'USE_X_SENDFILE':                       False,
    'LOGGER_NAME':                          None,
    'LOGGER_HANDLER_POLICY':               'always',
    'SERVER_NAME':                          None,
    'APPLICATION_ROOT':                     None,
    'SESSION_COOKIE_NAME':                  'session',
    'SESSION_COOKIE_DOMAIN':                None,
    'SESSION_COOKIE_PATH':                  None,
    'SESSION_COOKIE_HTTPONLY':              True,
    'SESSION_COOKIE_SECURE':                False,
    'SESSION_REFRESH_EACH_REQUEST':         True,
    'MAX_CONTENT_LENGTH':                   None,
    'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
    'TRAP_BAD_REQUEST_ERRORS':              False,
    'TRAP_HTTP_EXCEPTIONS':                 False,
    'EXPLAIN_TEMPLATE_LOADING':             False,
    'PREFERRED_URL_SCHEME':                 'http',
    'JSON_AS_ASCII':                        True,
    'JSON_SORT_KEYS':                       True,
    'JSONIFY_PRETTYPRINT_REGULAR':          True,
    'JSONIFY_MIMETYPE':                     'application/json',
    'TEMPLATES_AUTO_RELOAD':                None,

視圖函數取配置

要想在視圖函數中獲取配置文件的值,都是經過app.config來拿。app

可是若是視圖函數和Flask建立的對象app不在一個模塊。就得導入來拿。dom

能夠不用導入,直接導入一個current_app,這個就是當前的app對象,用current_app.config就能查看到了當前app的全部的配置文件函數

from flask import Flask,current_app
@app.route('/index',methods=["GET","POST"])
def index():
    print(current_app.config)   #當前的app的全部配置
    session["xx"] = "fdvbn"
    return "index"

路由系統

FBV 的路由添加方式

語法

@app.route(參數)

可選參數

rule

設置動態路由,路徑中能夠帶參數 ,必需要指定類型源碼分析

/index/<int:nid>

僅容許的類型 

  • string 字符串
  • float 浮點型
  • path 路徑
  • int 整型
  • any 任何
  • uuid uuid類型

默認的不支持正則路由匹配的

默認不指定的時候按str 處理

實例

from flask import Flask

# 將當前的運行的主程序構建成 Flask 應用, 以便去接受用戶的請求和響應
app = Flask(__name__)


# 路由定義, 目的是爲了匹配用戶的訪問路徑
# "/" 表示整個網站的根 " index " 表示自定義的訪問路徑
# index() 表示匹配上訪問路徑後的處理程序( views ), 此函數必需要有返回值 ( 字符串 / 模板文件 )
@app.route('/index')
def index():
    return "<h1> 這是個人網站的首頁 </h1>"


# 無參數
@app.route('/')
def first():
    return "This is my first flask demo"


# 單參數
@app.route('/name/<name>')
def name(name):
    return "This is {0} first flask".format(name)


# 帶類型的參數
@app.route('/num/<int:num>')
def num(num):
    return "get a unm: {0} ".format(num)


"""
可選的參數類型
    str:    字符串,不能加 "/" 
    int:    整數
    float:  浮點型
    path:   路徑,本質仍是字符串, 可是能夠加 "/" 
        不推薦使用 path 容易誤解
 """


# 多參數
# str 類型不須要加 <str:...>
@app.route('/more/<name>/<int:age>')
def more(name, age):
    return " name : {name} ; age: {age}".format(name=name, age=age)
    # return "name: %s ; age : %s" % (name, age)


if __name__ == '__main__':
    # debug = True  # 調試模式, 部署運行是設置爲 False
    app.run(debug=True)  # 啓動程序

多 URL 的路由匹配方式

容許多個路由匹配到同一個 視圖上

@app.route('/manyA/')
@app.route('/manyB/')
@app.route('/manyC/')
def many():
    return "我能夠匹配多個URL , 厲害吧"

URL 中適配正則的驗證方式

from flask import Flask,url_for

    app = Flask(__name__)

    # 定義轉換的類
    from werkzeug.routing import BaseConverter
    class RegexConverter(BaseConverter):
        """
        自定義URL匹配正則表達式
        """

        def __init__(self, map, regex):
            super(RegexConverter, self).__init__(map)
            self.regex = regex

        def to_python(self, value):
            """
            路由匹配時,匹配成功後傳遞給視圖函數中參數的值
            :param value: 
            :return: 
            """
            return int(value)

        def to_url(self, value):
            """
            使用url_for反向生成URL時,傳遞的參數通過該方法處理,返回的值用於生成URL中的參數
            :param value: 
            :return: 
            """
            val = super(RegexConverter, self).to_url(value)
            return val

    # 添加到converts中
    app.url_map.converters['regex'] = RegexConverter

    # 進行使用
    @app.route('/index/<regex("\d+"):nid>',endpoint='xx')
    def index(nid):
        url_for('xx',nid=123)  #反向生成,就會去執行to_url方法
        return "Index"

    if __name__ == '__main__':
        app.run()

default 添加默認值示例

from flask import Flask

app = Flask(__name__)

# 2. 函數index須要參數,可是url裏無參數,便可以用defaults={"k":"v"}爲函數提供參數
@app.route("/",methods=['GET','POST'],defaults={"nid":888})
# 1. 函數index須要參數,可是url裏無參數
def index(nid):
    print(nid)      # 會在工做它打印nid   888
    return "Hello World!"

if __name__ =="__main__":
    app.run()

strict_slashes 「/」 示例

@app.route('/index',strict_slashes=False),
    訪問 http://www.xx.com/index/ 或 http://www.xx.com/index都可
@app.route('/index',strict_slashes=True)
    僅訪問 http://www.xx.com/index 

redirect_to 重定向示例

原url有參數時,跳轉是也得傳參,注意:不用加類型

#/old
@app.route('/old/<int:nid>',redirect_to="/new/<nid>")
def old(nid):
    return "old"
# /new
@app.route('/new/<int:nid>')
def new(nid):
    return "new"

subdomain 子域名示例

from flask import Flask, views, url_for

app = Flask(import_name=__name__)
app.config['SERVER_NAME'] = 'haiyan.com:5000'


@app.route("/", subdomain="admin")
def static_index():
    return "admin.xxx.com"

#動態生成 @app.route("/dynamic", subdomain="<username>") def username_index(username): return username + ".your-domain.tld" if __name__ == '__main__': app.run()

路由系統的本質

經過源碼分析。
@app.route()的本質就是執行了 add_url_rule(rule,endpoint,f,**options) 方法
所以咱們也能夠在這裏操做也能夠添加路由映射 主流並非用這種。就裝飾器就能夠了

from flask import Flask

app = Flask(__name__)
app.config.from_object("settings.DevelopmentConfig")

'''
看到路由系統,分析路由系統幹了什麼?
第一步:先執行:decorator = app.route("/", methods= ['GET','POST'], endpoint='n1')
    根據源碼,第一步執行了下面的函數,返回decorator,這就是一個閉包,閉包給誰用,誰之後執行這個函數就給誰用
    def route(self, rule, **options):
        # 具體值與參數的對應關係:
        # app對象
        # rule = "/"
        # options = {methods= ['GET','POST'], endpoint='n1'}
        def decorator(f):
            endpoint = options.pop('endpoint', None)
            self.add_url_rule(rule, endpoint, f, **options)
            return f
        return decorator
第二步: 第一步返回了decorator,因此至關因而: @decorator,等價於decorator(index),觸發上面route函數下面的decorator函數的運行
        def decorator(f):
            endpoint = options.pop('endpoint', None)
            self.add_url_rule(rule, endpoint, f, **options)  # self就是app對象。加到了路由的對應表裏去了,那裏有url對應的函數
            return f
            
最後總結一下,添加路由關係的本質,其實就是最終執行 self.add_url_rule(rule, endpoint, f, **options),生成路由的對應關係 

'''
#  對於endpoint還要注意:
#  若是endpoint沒有寫,根據源碼可知,默認的就是函數名,即該路由對應函數,如index(endpoint = index)
@app.route("/", methods= ['GET','POST'], endpoint='n1')
def index():
    return "Hello World!"

def login():
    return "登陸"

# 因此根據源碼的原理,也能夠按照下面的方式添加路由對應關係,就與Django相似了。可是在Flask裏,仍是要按照裝飾器的方式去添加路由對應關係
app.add_url_rule('/login', 'n2', login, methods= ['GET','POST'])

if __name__ == "__main__":
    app.run()

CBV 的路由添加方式

def auth(func):
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        return result
    return inner


class IndexView(views.MethodView):
    # methods = ['POST']  #只容許POST請求訪問
    decorators = [auth,]  #若是想給全部的get,post請求加裝飾器,就能夠這樣來寫,也能夠單個指定

    def get(self):   #若是是get請求須要執行的代碼
        v = url_for('index')
        print(v)
        return "GET"

    def post(self):  #若是是post請求執行的代碼
        return "POST"

app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  #name指定的是別名,會當作endpoint使用
相關文章
相關標籤/搜索