You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实现JSON文件存储的静态地理数据的多语言翻译

问题核心原因

Django的makemessages命令仅会扫描代码中的字符串字面量作为待翻译词条,动态从JSON文件读取的变量内容不会被识别,因此你之前的写法里只有硬编码的--- Select a Country ---可以正常翻译。

下面是两种可直接落地的实现方案:


方案1:预生成翻译词条列表(推荐,无需修改原有JSON结构)

核心逻辑是提前把所有需要翻译的地名提取为静态字面量列表,让makemessages可以正常扫描,运行时的原有读取逻辑完全不用改。
操作步骤:

  1. 写一个自动提取脚本extract_geo_names.py,批量导出JSON中所有需要翻译的地名:
import json

def extract_names():
    # 替换为你的JSON文件路径
    with open('myproj/static/data/countries_states_cities.json', 'r', encoding='utf-8') as f:
        all_data = json.load(f)
    # 用set去重
    trans_names = set()
    for country in all_data:
        trans_names.add(country['name'])
        # 需要翻译省份、城市的话把下面注释打开
        # for state in country.get('states', []):
        #     trans_names.add(state['name'])
        #     for city in state.get('cities', []):
        #         trans_names.add(city['name'])
    
    # 生成供makemessages扫描的py文件
    with open('myproj/geo_translations.py', 'w', encoding='utf-8') as f:
        f.write('from django.utils.translation import gettext_lazy as _\n\n')
        f.write('# 仅用于扫描待翻译词条,不会被业务代码直接调用\n')
        f.write('GEO_TRANSLATIONS = [\n')
        for name in sorted(trans_names):
            escaped_name = name.replace('"', '\\"')
            f.write(f'    _("{escaped_name}"),\n')
        f.write(']\n')

if __name__ == '__main__':
    extract_names()
  1. 运行该脚本,会在项目根目录生成geo_translations.py文件。
  2. 执行django-admin makemessages -l fr命令,工具会自动扫描该文件中的所有地名,加入.po翻译文件,正常完成翻译后执行compilemessages编译即可。
  3. 你原来forms.py中的代码不需要做任何修改,运行时_(x['name'])会自动匹配已编译的翻译结果。

方案2:JSON内置多语言字段(适合多语言数据更新频繁的场景)

如果你不想维护Django的gettext翻译体系,可以直接给JSON增加多语言字段,运行时根据当前激活语言直接取值:

  1. 修改JSON结构,给需要翻译的字段增加多语言版本:
{
    "id": 1,
    "name": "Afghanistan",
    "name_trans": {
        "fr": "Afghanistan",
        "zh-hans": "阿富汗",
        "es": "Afganistán"
    },
    // 其他原有字段保持不变
}
  1. 修改forms.py中的读取逻辑:
from django.utils.translation import gettext_lazy as _
from django.utils import translation

def get_country():
    filepath = 'myproj/static/data/countries_states_cities.json'
    all_data = readJson(filepath)
    # 获取当前激活的语言
    current_lang = translation.get_language()
    all_countries = [('----', _("--- Select a Country ---"))]
    for x in all_data:
        # 找不到对应语言的翻译就回退到英文原名
        country_name = x['name_trans'].get(current_lang, x['name'])
        all_countries.append((x['name'], country_name))
    return all_countries

这种方案不需要执行makemessages和compilemessages命令,多语言数据直接维护在JSON中,适合有现成多语言地名数据集的场景。


注意事项

  • 采用方案1时,每次更新JSON中的地名后,都需要重新运行提取脚本、再执行makemessages更新翻译词条。
  • 地名翻译量大的话,可以直接找现成的ISO标准国家/省市多语言数据集,批量导入到po文件或者JSON的多语言字段中,无需手动逐条翻译。

内容的提问来源于stack exchange,提问作者ionecum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 04:36:02