可选的URL变量

Dem*_*cht 6 python url-routing flask

有没有办法在Flask中使用可选的URL参数定义URL?基本上,我想要做的是定义允许选择指定语言的规则:

/
/de -> matches / (but doesn't collide with /profile)
/profile 
/de/profile
Run Code Online (Sandbox Code Playgroud)

我想我已经找到了一种方法,但它涉及要么改变Werkzeug和Flask如何处理请求(猴子修补或分支框架源).这似乎是一个处理这个问题的过于复杂的方式..有一种更简单的方法可以做到这一点,我忽略了吗?

编辑:

基于Brian的回答,这是我想出的:

app.py:

from loc import l10n

def create_app(config):                                                                                                                 
    app = Flask(__name__)                                                                                                               
    app.config.from_pyfile(config)                                                                                                      

    bp = l10n.Blueprint()                                                                                                               
    bp.add_url_rule('/', 'home', lambda lang_code: lang_code)                                                                           
    bp.add_url_rule('/profile', 'profile', lambda lang_code: 'profile: %s' % 
        lang_code)
    bp.register_app(app)                                                                                                                

    return app  

if __name__ == '__main__':
    create_app('dev.cfg').run()
Run Code Online (Sandbox Code Playgroud)

LOC/l10ln.py

class Blueprint(Blueprint_):
    def __init__(self):
        Blueprint_.__init__(self, 'loc', __name__)

    def register_app(self, app):
        app.register_blueprint(self, url_defaults={'lang_code': 'en'})                                                                  
        app.register_blueprint(self, url_prefix='/<lang_code>')

        self.app = app
Run Code Online (Sandbox Code Playgroud)

(我还没有lang_code从变量列表中提取,但很快就会这样做)

现在那只是热门的imho.

Fog*_*ird 10

如果您不知道,可以为视图注册多条路线.对于每一种观点都可能是痛苦的,但它是可行的......

DEFAULT_LANG = 'en'

@app.route('/profile')
@app.route('/<lang>/profile')
def profile(lang=DEFAULT_LANG):
   pass
Run Code Online (Sandbox Code Playgroud)

或者,也许你可以实现自己的route装饰器,自动调用app.route两个场景......

from flask import Flask

app = Flask(__name__)

DEFAULT_LANG = 'en'

def lang_route(rule, **options):
    def decorator(f):
        endpoint = options.pop('endpoint', None)
        app.add_url_rule(rule, endpoint, f, **options)
        app.add_url_rule('/<lang>%s' % rule, endpoint, f, **options)
        return f
    return decorator

@lang_route('/profile') # also accepts '/<lang>/profile' automatically
def profile(lang=DEFAULT_LANG):
    return lang

if __name__ == '__main__':
    app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)


小智 9

蓝图可能适用于此,因为它们可以多次注册.

from flask import Flask, Blueprint

app = Flask(__name__)
bp = Blueprint('main', __name__)

@bp.route('/')
def hello(lang):
    return 'Hello ' + lang + '!'

app.register_blueprint(bp, url_defaults={'lang': 'en'})
app.register_blueprint(bp, url_prefix='/<lang>')

if __name__ == '__main__':
    app.run()
Run Code Online (Sandbox Code Playgroud)

如果可行,请参阅Flask文档中的国际化蓝图URL,以避免lang在每个视图函数中指定参数.