Flask - 无法覆盖需要不同子域的蓝图的默认子域
Flask - Can't override default subdomain for blueprints needing a different subdomain
我有一个 Flask project/app,希望它主要来自 app.example.com
。我在这个应用程序中也有一个蓝图,只能从 api.example.com
.
提供
现在,如果我将 app
设置为默认子域,我将无法在其他应从不同子域(例如 api
)提供服务的蓝图中覆盖此默认值。事实上,任何使用不同子域创建的蓝图都将出现 404。
换句话说,下面的代码不起作用(api.example.com/test2
将 404):
# -*- coding: utf-8 -*-
from flask import Flask, Blueprint
app = Flask(__name__)
app.config['SERVER_NAME'] = 'example.com'
app.url_map.default_subdomain = 'app' # set default subdomain, intending to override it below for `api.*`
appbp = Blueprint('app', 'app')
apibp = Blueprint('api', 'api')
@appbp.route('/test1')
def app_hello():
# this works (app.example.com/test1)
return 'appbp.app_hello'
@apibp.route('/test2')
def api_hello():
# this will 404 (api.example.com/test2)
return 'apibp.api_hello'
app.register_blueprint(appbp) # this works, serves from `app.example.com`
app.register_blueprint(apibp, subdomain='api') # doesn't work, `api.example.com/test2` will 404, so will `app.example.com/test2` (tried just in case it was using the default subdomain instead)
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888, debug=True)
但是,如果我不设置默认子域,而是 而是在每次注册蓝图时设置一个子域,那么 app
和 api
:
# -*- coding: utf-8 -*-
from flask import Flask, Blueprint
app = Flask(__name__)
app.config['SERVER_NAME'] = 'example.com'
# app.url_map.default_subdomain = 'app' # now try without a default
appbp = Blueprint('app', 'app')
apibp = Blueprint('api', 'api')
@appbp.route('/test1')
def app_hello():
# this works (app.example.com/test1)
return 'appbp.app_hello'
@apibp.route('/test2')
def api_hello():
# this works (api.example.com/test2)
return 'apibp.api_hello'
app.register_blueprint(appbp, subdomain='app') # works, explicitly set subdomain on each blueprint
app.register_blueprint(apibp, subdomain='api') # works, explicitly set subdomain on each blueprint
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888, debug=True)
在这两个示例中,蓝图似乎都注册了正确的子域:
<Rule 'app|/test1' (OPTIONS, GET, HEAD) -> app.app_hello>
<Rule 'api|/test2' (OPTIONS, GET, HEAD) -> api.api_hello>
但是,很明显,设置 app.url_map.default_subdomain
打算稍后覆盖它与仅手动显式设置子域之间存在差异。
知道这里发生了什么吗?
加分:以下哪一种是设置子域的首选方式?我已经看到它是双向的。
app.register_blueprint(apibp, subdomain='api')
对比
apibp = Blueprint('api', 'api', subdomain='api')
app.register_blueprint(apibp)
缺少的是 subdomain_matching
option for Flask()
:
subdomain_matching – consider the subdomain relative to SERVER_NAME
when matching routes. Defaults to False.
由于app
是相对名,需要设置为True
:
app = Flask(__name__, subdomain_matching=True)
这过去是隐式完成的,但从 Flask 1.0 开始,它是一个显式开关。进行更改是因为不同的人对设置 SERVER_NAME
的含义有不同的期望,请参阅 Flask issue #998。
至于在哪里设置subdomain
选项,那是你的选择。如果您在不同的上下文中重复使用蓝图,那么在 app.register_blueprint()
调用中设置子域选项更有意义,而在 Blueprint()
实例调用中设置它可能会使它更加自我记录,如果你是在靠近您的路线的地方创建该蓝图对象,因此想让处理该代码的人更清楚他们只影响特定的子域。
我有一个 Flask project/app,希望它主要来自 app.example.com
。我在这个应用程序中也有一个蓝图,只能从 api.example.com
.
现在,如果我将 app
设置为默认子域,我将无法在其他应从不同子域(例如 api
)提供服务的蓝图中覆盖此默认值。事实上,任何使用不同子域创建的蓝图都将出现 404。
换句话说,下面的代码不起作用(api.example.com/test2
将 404):
# -*- coding: utf-8 -*-
from flask import Flask, Blueprint
app = Flask(__name__)
app.config['SERVER_NAME'] = 'example.com'
app.url_map.default_subdomain = 'app' # set default subdomain, intending to override it below for `api.*`
appbp = Blueprint('app', 'app')
apibp = Blueprint('api', 'api')
@appbp.route('/test1')
def app_hello():
# this works (app.example.com/test1)
return 'appbp.app_hello'
@apibp.route('/test2')
def api_hello():
# this will 404 (api.example.com/test2)
return 'apibp.api_hello'
app.register_blueprint(appbp) # this works, serves from `app.example.com`
app.register_blueprint(apibp, subdomain='api') # doesn't work, `api.example.com/test2` will 404, so will `app.example.com/test2` (tried just in case it was using the default subdomain instead)
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888, debug=True)
但是,如果我不设置默认子域,而是 而是在每次注册蓝图时设置一个子域,那么 app
和 api
:
# -*- coding: utf-8 -*-
from flask import Flask, Blueprint
app = Flask(__name__)
app.config['SERVER_NAME'] = 'example.com'
# app.url_map.default_subdomain = 'app' # now try without a default
appbp = Blueprint('app', 'app')
apibp = Blueprint('api', 'api')
@appbp.route('/test1')
def app_hello():
# this works (app.example.com/test1)
return 'appbp.app_hello'
@apibp.route('/test2')
def api_hello():
# this works (api.example.com/test2)
return 'apibp.api_hello'
app.register_blueprint(appbp, subdomain='app') # works, explicitly set subdomain on each blueprint
app.register_blueprint(apibp, subdomain='api') # works, explicitly set subdomain on each blueprint
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888, debug=True)
在这两个示例中,蓝图似乎都注册了正确的子域:
<Rule 'app|/test1' (OPTIONS, GET, HEAD) -> app.app_hello>
<Rule 'api|/test2' (OPTIONS, GET, HEAD) -> api.api_hello>
但是,很明显,设置 app.url_map.default_subdomain
打算稍后覆盖它与仅手动显式设置子域之间存在差异。
知道这里发生了什么吗?
加分:以下哪一种是设置子域的首选方式?我已经看到它是双向的。
app.register_blueprint(apibp, subdomain='api')
对比
apibp = Blueprint('api', 'api', subdomain='api')
app.register_blueprint(apibp)
缺少的是 subdomain_matching
option for Flask()
:
subdomain_matching – consider the subdomain relative to
SERVER_NAME
when matching routes. Defaults to False.
由于app
是相对名,需要设置为True
:
app = Flask(__name__, subdomain_matching=True)
这过去是隐式完成的,但从 Flask 1.0 开始,它是一个显式开关。进行更改是因为不同的人对设置 SERVER_NAME
的含义有不同的期望,请参阅 Flask issue #998。
至于在哪里设置subdomain
选项,那是你的选择。如果您在不同的上下文中重复使用蓝图,那么在 app.register_blueprint()
调用中设置子域选项更有意义,而在 Blueprint()
实例调用中设置它可能会使它更加自我记录,如果你是在靠近您的路线的地方创建该蓝图对象,因此想让处理该代码的人更清楚他们只影响特定的子域。