使用URL处理器正确格式化规范URL结构

2024-05-19 10:28:52 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:你能仔细阅读我的问题吗?这个问题是具体的,而不是已经说过的duplicated。显然,我在发帖前读过这篇question。在


在这个来自docs的演示代码中,lang参数后面的片段将是静态的。所以,用英语/en/about,比如葡萄牙语/pt/about。正确的,应该是/pt/sobre。在

有没有关于正确的方法来使用URL处理器?在

from flask import Flask, g

app = Flask(__name__)

@app.url_defaults
def add_language_code(endpoint, values):
    if 'lang_code' in values or not g.lang_code:
        return
    if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
        values['lang_code'] = g.lang_code

@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code', None)

@app.route('/<lang_code>/')
def index():
    ...

@app.route('/<lang_code>/about')
def about():

Tags: ptappurl编辑flasklangifdef
1条回答
网友
1楼 · 发布于 2024-05-19 10:28:52

好的,你已经有了语言前缀。所以下一部分你需要几个翻译。在

最简单的方法是使用多种路径或转换器:

@app.route('/<lang_code>/about')
@app.route('/<lang_code>/sobre')
def about():
    pass

或者

^{pr2}$

但是很难支持和添加新的语言。在

第二种方法是改变路径方法来翻译特殊单词或添加特殊的翻译处理器转换器,最后一种更有趣和更含蓄:

^{3}$

但这个例子还有下一个问题:

/en/about
/en/sorbe
/pt/about
/pt/sorbe

是有效的URL,但您也可以尝试使用自己的Rule类(Flask.url_rule_class),在match方法中可以处理以下情况:

from werkzeug.routing import AnyConverter, Rule


class TranslateConverter(AnyConverter):

    def __init__(self, map, item):
        self.language_pairs = {language: translate_url(item, language)
                               for language in languages}
        AnyConverter.__init__(self, map, *tuple(self.language_pairs.values()))


class TranslateCorrelationRule(Rule):

    def match(self, path):
        result = Rule.match(self, path)
        if result is None:
            return result
        lang_code = result.get('lang_code')
        if lang_code is None:
            return result
        for name, value in self._converters.items():
            if not isinstance(value, TranslateConverter):
                continue
            if value.language_pairs[lang_code] != result[name]:
                return
        return result


app.url_map.converters['tr'] = TranslateConverter
app.url_rule_class = TranslateCorrelationRule

如果要简化url_for的用法,可以使用下一个示例:

@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
    if not values:
        return
    g.lang_code = values.pop('lang_code', None)
    for key, value in values.items():
        if key.startswith('_'):
            values.pop(key)


class TranslateCorrelationRule(Rule):

    def _update_translate_values(self, values):
        lang_code = values.get('lang_code', getattr(g, 'lang_code', None))
        if lang_code is None:
            return values
        values = values.copy()
        for argument in self.arguments:
            if argument in values:
                continue
            converter = self._converters[argument]
            if not isinstance(converter, TranslateConverter):
                continue
            values[argument] = converter.language_pairs[lang_code]
        return values

    def suitable_for(self, values, method=None):
        return Rule.suitable_for(self, self._update_translate_values(values),
                                 method)

    def build(self, values, append_unknown=True):
        return Rule.build(self, self._update_translate_values(values),
                          append_unknown)

相关问题 更多 >

    热门问题