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

如何实现Django网站全量翻译?含数据库新增内容翻译需求

Django 项目全量翻译方案(覆盖现有及新增数据库数据)

一、基础国际化配置

首先在项目配置中开启多语言支持:

# settings.py
USE_I18N = True
USE_L10N = True

# 配置支持的语言列表,按需添加
LANGUAGES = [
    ('zh-hans', '简体中文'),
    ('en', 'English'),
]

# 指定翻译文件存放目录(需手动创建locale文件夹)
LOCALE_PATHS = [
    BASE_DIR / 'locale',
]

# 调整中间件顺序,LocaleMiddleware需放在SessionMiddleware之后、CommonMiddleware之前
MIDDLEWARE = [
    # ... 其他中间件
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ... 其他中间件
]

二、静态文本翻译(模板、视图、模型字段名等)

处理非数据库动态内容,使用Django原生翻译机制:

1. 模板中使用翻译

<!-- templates/example.html -->
{% load i18n %}

<h1>{% trans "Welcome to our site" %}</h1>

{% blocktrans with username=user.name %}
Hello {{ username }}, thanks for visiting.
{% endblocktrans %}

2. 视图/代码中使用翻译

# views.py
from django.utils.translation import gettext as _

def my_view(request):
    message = _("This is a translated message")
    return render(request, 'example.html', {'message': message})

3. 生成并编译翻译文件

# 生成指定语言的翻译模板文件
python manage.py makemessages -l zh-hans
python manage.py makemessages -l en

# 编译翻译文件为Django可读取的格式
python manage.py compilemessages

编辑locale/zh-hans/LC_MESSAGES/django.po文件,填写对应翻译内容即可。

三、数据库动态内容翻译(核心需求)

针对数据库存储的动态内容(如文章标题、内容),提供两种方案覆盖现有及新增数据:

方案1:使用django-modeltranslation(推荐,开箱即用)

通过扩展模型字段实现多语言存储,无需额外关联模型。

步骤1:安装依赖

pip install django-modeltranslation

步骤2:配置应用

# settings.py
INSTALLED_APPS = [
    # ... 其他应用
    'modeltranslation',
]

步骤3:扩展模型字段

# models.py
from django.db import models
from modeltranslation.translator import register, TranslationOptions

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

@register(Article)
class ArticleTranslationOptions(TranslationOptions):
    # 指定需要翻译的字段,自动生成`title_en`、`title_zh_hans`等字段
    fields = ('title', 'content')

步骤4:执行数据库迁移

python manage.py makemigrations
python manage.py migrate

步骤5:批量翻译现有数据

编写脚本调用第三方翻译API(以百度翻译为例,需自行申请密钥)批量处理现有数据:

# scripts/translate_existing.py
import os
import sys
import requests
from django.conf import settings

# 初始化Django环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')
import django
django.setup()

from yourapp.models import Article

# 替换为你的翻译API密钥
APP_ID = 'your_app_id'
APP_KEY = 'your_app_key'

def translate(text, to_lang='en'):
    # 按照翻译API文档实现签名逻辑,此处省略
    url = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
    params = {
        'q': text,
        'from': 'auto',
        'to': to_lang,
        'appid': APP_ID,
        'salt': '123',
        'sign': 'your_generated_sign'
    }
    resp = requests.get(url, params=params)
    result = resp.json()
    return result['trans_result'][0]['dst'] if 'trans_result' in result else text

if __name__ == '__main__':
    for article in Article.objects.all():
        article.title_en = translate(article.title, 'en')
        article.content_en = translate(article.content, 'en')
        article.save(update_fields=['title_en', 'content_en'])
        print(f"Translated article {article.id}")

运行脚本:python scripts/translate_existing.py

步骤6:自动处理新增数据

使用post_save信号,新增数据时自动触发翻译:

# yourapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from yourapp.models import Article
from yourapp.utils import translate  # 将上面的translate函数放到utils.py

@receiver(post_save, sender=Article)
def translate_new_article(sender, instance, created, **kwargs):
    if created:
        instance.title_en = translate(instance.title, 'en')
        instance.content_en = translate(instance.content, 'en')
        instance.save(update_fields=['title_en', 'content_en'])

在apps.py中注册信号:

# yourapp/apps.py
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'yourapp'

    def ready(self):
        import yourapp.signals

步骤7:优化Admin界面

# yourapp/admin.py
from django.contrib import admin
from modeltranslation.admin import TranslationAdmin
from yourapp.models import Article

class ArticleAdmin(TranslationAdmin):
    list_display = ('title', 'created_at')

admin.site.register(Article, ArticleAdmin)

方案2:自定义翻译模型(灵活可控,不修改原模型)

创建独立模型存储多语言内容,适合无需改动原模型结构的场景。

步骤1:创建翻译模型

# models.py
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType

class Translation(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    
    field_name = models.CharField(max_length=50)
    language = models.CharField(max_length=10)
    translated_text = models.TextField()

    class Meta:
        unique_together = ('content_type', 'object_id', 'field_name', 'language')

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    
    translations = GenericRelation(Translation)

    def get_translated(self, field_name):
        from django.utils.translation import get_language
        lang = get_language()
        trans = self.translations.filter(field_name=field_name, language=lang).first()
        return trans.translated_text if trans else getattr(self, field_name)

步骤2:批量处理现有数据

类似方案1,编写脚本生成翻译记录:

# scripts/translate_existing.py
# 初始化Django环境...
from yourapp.models import Article, Translation
from yourapp.utils import translate

for article in Article.objects.all():
    Translation.objects.get_or_create(
        content_object=article,
        field_name='title',
        language='en',
        defaults={'translated_text': translate(article.title, 'en')}
    )
    Translation.objects.get_or_create(
        content_object=article,
        field_name='content',
        language='en',
        defaults={'translated_text': translate(article.content, 'en')}
    )

步骤3:自动处理新增数据

同样使用post_save信号生成翻译记录,逻辑与方案1类似,此处省略。

步骤4:模板中调用翻译

<!-- templates/article_detail.html -->
<h1>{{ article.get_translated('title') }}</h1>
<div>{{ article.get_translated('content') }}</div>

四、URL路由国际化

为URL添加语言前缀,支持用户切换语言:

# urls.py
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('i18n/', include('django.conf.urls.i18n')),  # 语言切换接口
]

urlpatterns += i18n_patterns(
    path('admin/', admin.site.urls),
    path('', include('yourapp.urls')),
)

模板中添加语言切换表单:

<!-- templates/base.html -->
<form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <input name="next" type="hidden" value="{{ redirect_to }}">
    <select name="language">
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}
        {% for lang in languages %}
            <option value="{{ lang.code }}" {% if lang.code == LANGUAGE_CODE %}selected{% endif %}>
                {{ lang.name_local }} ({{ lang.code }})
            </option>
        {% endfor %}
    </select>
    <input type="submit" value="Switch">
</form>

五、注意事项

  • 翻译API选择:可使用百度翻译、DeepL、谷歌翻译等,注意API调用限制与费用。
  • 错误处理:在翻译逻辑中添加异常捕获,避免翻译失败导致数据保存中断。
  • 缓存优化:对频繁访问的翻译内容使用Django缓存,减少API调用次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:57:09