Flask flask-babel插件实现国际化

项目背景:

web项目中,无论是给端上API还是服务API,往往都会设置统一格式返回,全局异常拦截等等功能。 统一格式例如

{
    "code": 100010,
    "message": "tenant is not exist",
    "data": ""
}

国际化主要针对的是messages参数实现多语言化,下面我们将手把手的实现这个功能。

网上的坑

主要是随着包的升级出现的不兼容问题。

flask国际化实现是通过插件flask-babel包,flask-babel包从2.0.0 到3.0.0大版本升级

去掉了localeselector方法

优化成了在初始化Babel的时候传入select_locale参数

如果你使用的最新的flask-babel,

# 设置语言选择逻辑
@babel.localeselector
def get_locale():
    # 从 URL 参数获取语言选择,如果没有提供则使用浏览器默认语言
    return request.args.get('lang', request.accept_languages.best_match(app.config['LANGUAGES']))

 上面方法localeselector方法提示不存在。

实现国际化完整流程

1、创建Flask项目

项目结构

babel-demo/
│
├── app.py          # Flask 应用主文件
├── config.py       # 配置文件
└── templates/
    └── index.html  # 模板文件

2. 安装依赖

首先,确保你安装了 Flask 和最新版的 Flask-Babel

pip install Flask Flask-Babel

3. 配置 Flask 和 Flask-Babel

config.py 中设置配置参数:

# config.py

class Config:
    LANGUAGES = ['en', 'zh']  # 支持的语言列表
    BABEL_DEFAULT_LOCALE = 'en'  # 默认语言
    BABEL_TRANSLATION_DIRECTORIES = 'translations'  # 翻译文件目录
 

 app.py启动文件

import json

from flask import Flask, render_template, request, jsonify
from flask_babel import Babel, _

app = Flask(__name__)
app.config.from_object('config.Config')

babel = Babel(app)


# 选择语言的函数
def select_locale():
    lang = request.args.get('lang', request.accept_languages.best_match(app.config['LANGUAGES']))
    print(f"Selected language: {lang}") 
    return lang


babel.init_app(app, locale_selector=select_locale)


# 上下文处理器,用于在模板中获取当前语言
@app.context_processor
def inject_locale():
    return {'get_locale': select_locale}


@app.route('/')
def index():
    return render_template('index.html')


if __name__ == "__main__":
    app.run()

 创建页面模板templates下面index.html

<!DOCTYPE html>
<html lang="{{ get_locale() }}">
<head>
    <meta charset="UTF-8">
    <title>{{ _("Hello World") }}</title>
</head>
<body>
    <h1>{{ _("Hello World") }}</h1>
    <p>{{ _("Welcome to our website.") }}</p>
</body>
</html>

4、创建翻译文件

为了支持多语言,你需要生成翻译文件。首先,创建 babel.cfg 文件,指定要提取翻译的文件类型:

# babel.cfg

[python: babel-demo/**.py]   # 扫描的文件
[jinja2: **/templates/**.html]
 

然后,使用以下命令提取项目中的可翻译字符串:

pybabel extract -F babel.cfg -o messages.pot .

接下来,为每种语言初始化翻译文件(例如英语和中文):

pybabel init -i messages.pot -d translations -l en
pybabel init -i messages.pot -d translations -l zh

 然后,编辑生成的 .po 文件,添加翻译文本。例如,translations/zh/LC_MESSAGES/messages.po 文件:

msgid "Hello World"
msgstr "你好,世界"

msgid "Welcome to our website."
msgstr "欢迎来到我们的网站。"

 最后,编译翻译文件:

pybabel compile -d translations

测试效果

现在,你可以运行 Flask 应用程序,并通过 URL 参数来切换语言。例如:

  • 默认语言(英语):http://localhost:5000/
  • 中文:http://localhost:5000/?lang=zh

 项目中实践

项目全局统一格式

web项目中我们对所有的api接口都统一格式返回。通过flask注解@app.after_request装饰器,用于注册一个函数,该函数将在每次请求后被调用。

@app.after_request
def after_request(response):
    print(f"Response status code: {response.status_code}")
    if response.is_json:
        data = response.get_json()
        if 'message' in data and isinstance(data['message'], str):
            data['message'] = _(data['message'])
        response.set_data(json.dumps(data))
    return response

获取全局返回结果,并查看是否包含message参数,如果包含,通过_()方式实现多语言。

全局捕捉异常

@app.errorhandler(Exception)
def handle_error(e):
    print(f"Handling error: {e}")
    error_message = str(e)
    response = {
        "status": "error",
        "message": error_message,
    }
    return jsonify(response), 400

这样就可以实现flask项目实现国际化。

一个api请求的过程

  • 24
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值