2012-11-24 43 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與語言代碼,但更美麗的解決方案是使用藍圖。「 –