2012-11-24 45 views
6

Có cách nào để xác định URL có tham số URL tùy chọn trong Flask không? Về cơ bản, những gì tôi muốn làm là xác định quy tắc cho phép cho các ngôn ngữ tùy chọn chỉ định:Biến URL tùy chọn

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

Tôi nghĩ rằng tôi đã tìm ra một cách để làm điều đó, nhưng nó liên quan đến một trong hai thực hiện một thay đổi như thế nào Werkzeug và Flask xử lý yêu cầu (hoặc khỉ vá hoặc giả mạo nguồn khung). Điều này có vẻ như một cách quá phức tạp để đối phó với vấn đề này mặc dù .. Có cách nào dễ dàng hơn để làm điều này mà tôi nhìn?

Edit:

Dựa trên câu trả lời của Brian, đây là những gì tôi đã đưa ra:

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 

(Tôi chưa nhận được để kéo lang_code từ danh sách biến nhưng sẽ sớm thực hiện việc đó)

Bây giờ đó chỉ là imho nóng.

Trả lời

7

Bản thiết kế có thể hoạt động vì điều này, vì chúng có thể được đăng ký nhiều lần.

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

Nếu thành công, xem Internationalized Blueprint URLs trong tài liệu Flask kiếm một cách để tránh việc chỉ định một lập luận lang trong mọi chức năng xem.

+0

Chắc chắn là con đường để đi imho, với độ nóng mới (tương đối) của bản thiết kế –

10

Chỉ trong trường hợp bạn không biết, bạn có thể đăng ký nhiều tuyến cho một chế độ xem. Có thể là một nỗi đau để làm điều đó cho mọi quan điểm, nhưng nó doable ...

DEFAULT_LANG = 'en' 

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

Hoặc, có lẽ bạn có thể thực hiện route trang trí của riêng bạn mà tự động gọi app.route cho cả hai kịch bản ...

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

Tôi nghĩ đây là một câu trả lời tuyệt vời và cực kỳ kỹ lưỡng. – jdotjdot

+0

100% cách phù hợp để thực hiện điều đó. – sberry

+1

Đây không phải là giải pháp tồi, nhưng tôi nghĩ rằng bản thiết kế chính xác hơn vì chúng được thiết kế để gói gọn một tập hợp các tuyến đường và cho phép bạn dễ dàng thao tác tất cả các tuyến đó cùng một lúc. [Flask docs recommend] (http://flask.pocoo.org/docs/patterns/urlprocessors/#internationalized-application-urls) bằng cách sử dụng bản thiết kế cho quốc tế hóa URL: "Bạn có thể cải thiện hơn nữa bằng cách viết trang trí của riêng bạn có tiền tố URL với mã ngôn ngữ, nhưng giải pháp đẹp hơn đang sử dụng bản thiết kế. " –

Các vấn đề liên quan