如何实现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
相关产品推荐
相关产品推荐

