2012-11-24 40 views
6

有没有一种方法可以在Flask中使用可选的URL参数定义URL?从本质上讲,我想要做的就是定义规则,允许随意指定的语言:可选的URL变量

/ 
/de -> matches/(but doesn't collide with /profile) 
/profile 
/de/profile 

我想我已经想出了一个办法做到这一点,但它涉及要么进行更改如何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() 

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 

(我还没有得到来自变量列表拉lang_code尚未,但将这样做不久)

现在这只是热恕我直言。

回答

7

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

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() 

如果这样的作品,看到Internationalized Blueprint URLs的瓶文档中的一种方式,以避免指定在每个视图功能lang说法。

+0

肯定是迈向imho的方式,考虑到蓝图 –

10

以防万一您不知道,您可以注册多个路线查看。可能是一个痛苦的做每一个看法,但它是可行的......

DEFAULT_LANG = 'en' 

@app.route('/profile') 
@app.route('/<lang>/profile') 
def profile(lang=DEFAULT_LANG): 
    pass 

或者,也许你能实现自己的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) 
+0

的(相对)新热度,我认为这是一个伟大而非常彻底的答案。 – jdotjdot

+0

100%正确的做法。 – sberry

+1

这不是一个坏的解决方案,但我认为蓝图更为正确,因为它们旨在封装一组路线,并让您轻松地一次处理所有这些路线。使用蓝图进行URL国际化的[Flask文档推荐](http://flask.pocoo.org/docs/patterns/urlprocessors/#internationalized-application-urls):“您可以通过编写自己的装饰器来加以改进,前缀为URL与语言代码,但更美丽的解决方案是使用蓝图。“ –