Flask Babel在重构蓝图项目后不起作用

0 投票
2 回答
24 浏览
提问于 2025-04-14 17:26

我有一个应用程序,使用flask babel进行翻译,运行得很好。

然后,我开始把代码拆分成模块,并生成蓝图,而不是把所有代码都写在同一个.py文件里。

这是我的项目结构:

项目结构

接下来,这是主文件的代码:FinMapper.py

from app import create_app

app = create_app('default')

app/init.py的代码

from flask import Flask
from flask_babel import Babel
from config import config


def register_blueprints(app):
    from .file_import import file_import_blueprint
    app.register_blueprint(file_import_blueprint)


def get_locale():
    return 'es'


babel = Babel()


def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    register_blueprints(app)
    babel.init_app(app)

    return app

forms.py中的代码:

class MovementFileForm(FlaskForm):
    type = SelectField(lazy_gettext('Type'), choices=[('default', 'DEFAULT'), ('bbva', 'BBVA')])
    file = FileField(lazy_gettext('File'),
                     validators=[DataRequired(),
                                 FileAllowed(['csv'], message='FileExtensionNotAllowed')],
                     render_kw={"class": "form-control"})

在重构以创建蓝图之前,lazy_gettext('text')的调用是可以正常工作的。

这里是带有导航栏的base.html示例:

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="#"><b>FinMapper</b></a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">{{ _('Dashboard') }}</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">{{ _('Categories') }}</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">{{ _('Categorize') }}</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="{{ url_for('file_import_blueprint.load') }}">{{ _('Load') }}</a>
                </li>
            </ul>
        </div>
    </div>
</nav>

和lazy_gettext一样,方法调用 _('text') 在创建蓝图之前也是可以正常工作的。

我主要的疑问是应用工厂中的这段代码是否正确,我觉得这里可能有问题:

Babel声明细节

这是没有蓝图时的第一版代码,运行得很好:

没有蓝图的项目

我不知道Babel应该如何实例化或声明,以便在所有蓝图中使用。现在,我的翻译功能不工作。

更新

我能够调用语言选择器,但仍然没有翻译。如果我这样配置babel:

babel = babel()

def create_app(config_name):
    app = Flask(__name)
    babel.init(app, locale_selector=gel_locale()
    # more coding

在get_locale函数中放一个打印语句,它可以正常工作,被调用了。但翻译仍然不行。

2 个回答

0

简短回答:

你引用的是你函数的调用,而不是函数本身。

而且你可能在 init_app 上写错了。

请把:

babel.init(app, locale_selector=gel_locale())

改成

babel.init_app(app, locale_selector=gel_locale)

解释说明

如果你在使用 Flask-Babel 4.0.x 版本,@localeselector 这个装饰器已经不存在了,你需要在创建 babel 实例时,把函数作为 localselector 参数来引用。

不过,如果你使用的是应用工厂模式(也就是在一个函数里创建你的应用,而不是直接在文件里),你应该在 init_app 里声明 local_selector 函数,而不是在创建 Babel 实例的时候。

例如:

from flask import Flask
from flask_babel import Babel
from config import my_config

babel = Babel()

def get_locale():
    # put your code to manage your user favorite language here
    # I recommend using flask session in order to maintain persistence between requests 

    return "en"

def create_app():
    app = Flask(__name__)
    app.config.from_object(my_config)
    babel.init_app(app, locale_selector=get_locale)
    
    return app
0

解决了将翻译文件夹移动到应用程序内部的问题。

你可以看到第一张照片是旧项目的结构。

现在,这是新的项目结构:

新项目结构

撰写回答