返回博客

如何使用 AI 翻译 Django 数据库内容

2026-02-18 4 分钟阅读
如何使用 AI 翻译 Django 数据库内容

如果你使用过 Django 内置的国际化 (i18n) 框架,就会知道它在处理静态字符串方面表现出色。将文本包装在 gettext() 中或使用 {% trans %} 模板标签可以将字符串提取到 .po 文件中,然后由翻译人员填写。这个系统经过了实战检验,在代码和模板中运行良好。

但是,存储在数据库中的内容怎么办呢?

产品名称、文章标题、分类描述、常见问题解答、用户生成的内容。这些都不在你的源代码中。Django 的 makemessages 命令永远找不到它们,.po 文件也无法帮助你。如果你的应用程序需要以多种语言向用户提供动态内容,你需要一种不同的策略。

下面是解决方法:使用 django-modeltranslation 为模型添加可翻译字段,然后使用 TranslateBot 通过 AI 自动完成翻译。

Django 数据库翻译包

有几个第三方包可以解决数据库翻译问题,每个包的架构各不相同。

django-modeltranslation

直接在现有表中添加特定语言的列。一个 title 字段会变成 title_entitle_detitle_fr 等。查询速度很快,因为所有数据都在同一张表中。管理界面可以并排显示所有语言。

django-parler

为每个模型创建一个单独的翻译表。原始表保持简洁,翻译存储在通过外键关联的相关表中。

django-translations

使用单个翻译表,通过通用外键指向任何模型。所有模型的所有翻译都存储在一张表中。

手动 JSON 字段

你可以将翻译存储在 JSONField 中:

class Product(models.Model):
    name_translations = models.JSONField(default=dict)
    # {"en": "Running Shoes", "de": "Laufschuhe", "fr": "Chaussures de course"}

应该选择哪个?

对于大多数项目来说,django-modeltranslation 是最佳选择。它是最成熟的包,拥有最好的 Django 管理后台集成,并且将所有数据保存在同一张表中以实现快速查询。其权衡(更宽的表和每增加一种新语言需要一次迁移)对于绝大多数应用来说是可以接受的。本指南的其余部分将使用 django-modeltranslation。

逐步设置 django-modeltranslation

第 1 步:安装包

TranslateBot 将 django-modeltranslation 作为可选依赖捆绑提供。一次性安装两者:

pip install translatebot-django[modeltranslation]

或者如果你使用 uv:

uv add --dev translatebot-django[modeltranslation]

第 2 步:配置 Django 设置

settings.py 中有两件事很重要:应用顺序和语言列表。

# settings.py

INSTALLED_APPS = [
    'modeltranslation',          # Must be BEFORE django.contrib.admin
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Your apps
    'shop',
    'translatebot_django',
]

LANGUAGE_CODE = 'en'

LANGUAGES = [
    ('en', 'English'),
    ('de', 'German'),
    ('fr', 'French'),
    ('nl', 'Dutch'),
]

modeltranslation 应用必须在 django.contrib.admin 之前,这样它才能修补管理类以显示翻译字段。

第 3 步:注册需要翻译的模型

在每个包含可翻译模型的应用中创建一个 translation.py 文件。以电商应用为例:

# shop/translation.py

from modeltranslation.translator import register, TranslationOptions
from .models import Product, Category


@register(Product)
class ProductTranslationOptions(TranslationOptions):
    fields = ('name', 'description', 'short_description')


@register(Category)
class CategoryTranslationOptions(TranslationOptions):
    fields = ('name', 'description')

只包含包含人类可读文本的字段。不要注册 slugpricesku 等字段。

第 4 步:创建并运行迁移

python manage.py makemigrations
python manage.py migrate

完成后,你的 shop_product 表将拥有新的列:

列名 类型
name varchar(200)
name_en varchar(200)
name_de varchar(200)
name_fr varchar(200)
name_nl varchar(200)
description text
description_en text
description_de text
description_fr text
description_nl text
short_description text
short_description_en text
short_description_de text
short_description_fr text
short_description_nl text

你在 LANGUAGES 中定义的每种语言都会为每个注册字段获得自己的列。

问题:空的翻译字段

现在你已经有了表结构,但每个 _de_fr_nl 列都是空的。如果你有 500 个产品,每个产品有 3 个可翻译字段和 3 种目标语言,那就是 4,500 个等待填充的空字段。

手动翻译这些内容是不现实的。即使使用专业翻译服务,你也需要导出数据、发送出去、等待交付,然后将结果导入回来。对于小团队或独立开发者来说,这通常意味着该功能永远不会上线。

这就是 TranslateBot 发挥作用的地方。

使用 TranslateBot 自动化翻译

TranslateBot 的 translate 管理命令可以使用 AI 填充所有这些空字段。首先配置你的 API 密钥:

# settings.py

TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"  # Fast and cost-effective

然后将所有注册的模型翻译为目标语言:

python manage.py translate --target-lang de --models

这一条命令就能找到所有在 django-modeltranslation 中注册的模型,识别目标语言中为空的字段,并用 AI 生成的翻译填充它们。

翻译特定模型

如果你只想翻译产品而不是分类:

python manage.py translate --target-lang de --models Product

或者翻译多个特定模型:

python manage.py translate --target-lang de --models Product Category

使用试运行预览

在写入数据库之前始终先预览:

python manage.py translate --target-lang de --models --dry-run

这会准确显示将要翻译的内容,而不会修改任何记录。

重新翻译现有内容

默认情况下,TranslateBot 会跳过已有翻译的字段。要覆盖现有翻译(例如,在改进 AI 模型或添加上下文之后):

python manage.py translate --target-lang de --models --overwrite

一次翻译所有语言

如果你省略 --target-lang 并且在设置中定义了 LANGUAGES,TranslateBot 会翻译为所有配置的语言:

python manage.py translate --models

翻译管道的工作原理

以下是运行翻译命令时发生的事情。

  1. 发现。 TranslateBot 查询 django-modeltranslation 的注册表,找到所有注册的模型及其可翻译字段。

  2. 源语言检测。 对于每条记录,它读取源内容。首先检查基础字段(例如 name),然后回退到第一个有内容的语言特定字段(例如 name_en)。没有源内容的记录会被跳过。

  3. 批处理。 记录被分组为批次并发送到 AI 提供商。这使 API 调用保持高效并避免触及速率限制。

  4. 翻译。 每个批次使用配置的 AI 模型进行翻译。你可以使用 LiteLLM 支持的任何 LLM 提供商(OpenAI、Anthropic、Google、Azure 以及许多其他提供商)或 DeepL。

  5. 原子写入。 一次翻译运行的所有数据库更新都包装在一个事务中。如果出现任何问题,如 API 错误或数据库约束违反,不会保存任何部分数据。要么全部成功,要么全部失败。

完整工作流示例

以下是从模型定义到翻译内容的完整示例,使用电商 Product 模型。

定义模型

# shop/models.py

from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    short_description = models.CharField(max_length=500, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    sku = models.CharField(max_length=50, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

注册翻译

# shop/translation.py

from modeltranslation.translator import register, TranslationOptions
from .models import Product


@register(Product)
class ProductTranslationOptions(TranslationOptions):
    fields = ('name', 'description', 'short_description')

运行迁移

python manage.py makemigrations shop
python manage.py migrate

添加翻译上下文(可选)

在项目根目录创建一个 TRANSLATING.md 文件,为 AI 提供产品领域的上下文:

# Translation Context

## About This Project
E-commerce store for outdoor sports equipment.

## Terminology
- "trail runners" refers to trail running shoes, not people
- Keep brand names (Nike, Salomon, Arc'teryx) untranslated
- "Gore-Tex" is a brand name, do not translate

## Tone
- Use informal "du" form in German
- Product descriptions should sound enthusiastic but not exaggerated

翻译

# Preview first
python manage.py translate --target-lang de --models Product --dry-run

# Apply translations
python manage.py translate --target-lang de --models Product

输出:

Translating Product model fields to German (de)...
Found 142 products with untranslated fields
Translating batch 1/15...
Translating batch 2/15...
...
Translating batch 15/15...
Successfully translated 142 products

在管理后台中验证

打开 Django 管理后台并进入任意产品。你将看到翻译字段已填充:

对每种目标语言重复此操作:

python manage.py translate --target-lang fr --models Product
python manage.py translate --target-lang nl --models Product

或一次翻译所有语言:

python manage.py translate --models Product

最佳实践

在生产环境中运行批量翻译之前,请备份数据库。TranslateBot 使用原子事务,因此失败的运行不会留下部分数据。但备份可以在翻译质量不符合预期时让你有回退的方法。

# PostgreSQL example
pg_dump mydb > backup_before_translation.sql

先使用试运行。在对新模型或新语言应用翻译之前,始终使用 --dry-run 运行。检查输出以确保源内容被正确检测,翻译结果看起来合理。

对于大型数据库,一次翻译一个模型。这样更容易审查结果,并在需要时重新运行特定模型。

python manage.py translate --target-lang de --models Product
python manage.py translate --target-lang de --models Category
python manage.py translate --target-lang de --models Article

添加翻译上下文。包含特定领域术语和语气指南的 TRANSLATING.md 文件可以显著提高翻译质量。这对于医学、法律或技术产品等专业领域尤为重要。

保持源语言字段填充。TranslateBot 从基础字段或源语言字段读取。确保你的数据录入工作流程始终填充源语言。空的源字段意味着空的翻译。

结合 PO 文件翻译以实现完全覆盖。同时翻译代码字符串和数据库内容:

# Static strings in code and templates
python manage.py makemessages -l de -l fr -l nl
python manage.py translate
python manage.py compilemessages

# Dynamic content in the database
python manage.py translate --models

这样你的用户看到的每个字符串,无论是来自模板还是数据库,都已被翻译。

下一步

停止手动编辑 .po 文件

TranslateBot 使用 AI 自动化 Django 翻译。一条命令,覆盖所有语言,每次翻译仅需几分钱。