Django国际化
一、今日学习内容概述
学习模块 | 重要程度 | 主要内容 |
---|---|---|
国际化基础 | ⭐⭐⭐⭐⭐ | 基本概念、配置设置 |
字符串翻译 | ⭐⭐⭐⭐⭐ | 翻译标记、消息文件 |
模板国际化 | ⭐⭐⭐⭐ | 模板标签、过滤器 |
动态内容翻译 | ⭐⭐⭐⭐ | 模型字段、表单翻译 |
二、国际化基础配置
# settings.py
# 启用国际化
USE_I18N = True
# 启用本地化
USE_L10N = True
# 启用时区
USE_TZ = True
# 支持的语言
LANGUAGES = [
('en', 'English'),
('zh-hans', '简体中文'),
('ja', '日本語'),
]
# 默认语言
LANGUAGE_CODE = 'en'
# 翻译文件路径
LOCALE_PATHS = [
BASE_DIR / 'locale',
]
# 中间件配置
MIDDLEWARE = [
# ...
'django.middleware.locale.LocaleMiddleware',
# ...
]
三、代码中的字符串翻译
# models.py
from django.db import models
from django.utils.translation import gettext_lazy as _
class Article(models.Model):
STATUS_CHOICES = [
('draft', _('草稿')),
('published', _('已发布')),
]
title = models.CharField(_('标题'), max_length=200)
content = models.TextField(_('内容'))
status = models.CharField(
_('状态'),
max_length=10,
choices=STATUS_CHOICES,
default='draft'
)
created_at = models.DateTimeField(_('创建时间'), auto_now_add=True)
class Meta:
verbose_name = _('文章')
verbose_name_plural = _('文章')
# views.py
from django.utils.translation import gettext as _
from django.contrib import messages
def article_create(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save()
messages.success(request, _('文章创建成功!'))
return redirect('article_detail', pk=article.pk)
else:
form = ArticleForm()
return render(request, 'articles/create.html', {
'title': _('创建新文章'),
'form': form
})
四、模板国际化
<!-- templates/base.html -->
{% load i18n %}
<!DOCTYPE html>
<html>
<head>
<title>{% trans "我的网站" %}</title>
</head>
<body>
<header>
<h1>{% trans "欢迎访问" %}</h1>
<div class="language-selector">
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ request.path }}">
<select name="language" onchange="this.form.submit()">
{% get_current_language as CURRENT_LANGUAGE %}
{% get_available_languages as LANGUAGES %}
{% for code, name in LANGUAGES %}
<option value="{{ code }}"
{% if code == CURRENT_LANGUAGE %}selected{% endif %}>
{{ name }}
</option>
{% endfor %}
</select>
</form>
</div>
</header>
<nav>
<ul>
<li><a href="{% url 'home' %}">{% trans "首页" %}</a></li>
<li><a href="{% url 'about' %}">{% trans "关于" %}</a></li>
<li><a href="{% url 'contact' %}">{% trans "联系我们" %}</a></li>
</ul>
</nav>
<main>
{% block content %}{% endblock %}
</main>
<footer>
{% blocktrans %}
版权所有 © {{ year }} 我的网站
{% endblocktrans %}
</footer>
</body>
</html>
五、国际化流程图
六、消息文件管理
6.1 创建和编译消息文件
# 创建/更新消息文件
python manage.py makemessages -l zh_hans
python manage.py makemessages -l ja
# 编译消息文件
python manage.py compilemessages
6.2 消息文件示例
# locale/zh_hans/LC_MESSAGES/django.po
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-19 10:00+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: models.py:8
msgid "标题"
msgstr "Title"
#: models.py:9
msgid "内容"
msgstr "Content"
#: templates/base.html:4
msgid "我的网站"
msgstr "My Website"
七、动态内容翻译
7.1 模型翻译
# models.py
from django.db import models
from django.utils.translation import gettext_lazy as _
class TranslatableModel(models.Model):
"""可翻译内容的基类"""
class Meta:
abstract = True
class ArticleTranslation(models.Model):
article = models.ForeignKey('Article', on_delete=models.CASCADE)
language = models.CharField(max_length=10, choices=settings.LANGUAGES)
title = models.CharField(max_length=200)
content = models.TextField()
class Meta:
unique_together = ('article', 'language')
class Article(TranslatableModel):
# 基本字段保持原样
created_at = models.DateTimeField(auto_now_add=True)
def get_translation(self, language=None):
"""获取指定语言的翻译"""
if language is None:
language = get_language()
try:
return self.articletranslation_set.get(language=language)
except ArticleTranslation.DoesNotExist:
# 如果没有找到翻译,返回默认语言
return self.articletranslation_set.get(
language=settings.LANGUAGE_CODE
)
7.2 表单翻译
# forms.py
from django import forms
from django.utils.translation import gettext_lazy as _
class ContactForm(forms.Form):
name = forms.CharField(
label=_('姓名'),
max_length=100,
error_messages={
'required': _('请输入您的姓名'),
'max_length': _('姓名长度不能超过100个字符'),
}
)
email = forms.EmailField(
label=_('电子邮箱'),
error_messages={
'required': _('请输入您的电子邮箱'),
'invalid': _('请输入有效的电子邮箱地址'),
}
)
message = forms.CharField(
label=_('留言内容'),
widget=forms.Textarea,
error_messages={
'required': _('请输入留言内容'),
}
)
八、URL国际化
# urls.py
from django.conf.urls.i18n import i18n_patterns
from django.urls import path, include
urlpatterns = [
path('i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
)
九、JavaScript国际化
// static/js/i18n.js
const gettext = function(msgid) {
return window.TRANSLATIONS[msgid] || msgid;
};
const interpolate = function(fmt, obj) {
return fmt.replace(/%\(\w+\)s/g, function(match) {
return String(obj[match.slice(2,-2)]);
});
};
// 使用示例
const message = gettext('欢迎访问,%(name)s!');
const welcomeMessage = interpolate(message, {name: 'John'});
十、日期和数字格式化
# views.py
from django.utils.formats import date_format, number_format
from django.utils import translation
def format_example(request):
current_language = translation.get_language()
# 格式化日期
today = date.today()
formatted_date = date_format(today, format='DATETIME_FORMAT')
# 格式化数字
number = 1234567.89
formatted_number = number_format(
number,
decimal_pos=2,
use_l10n=True
)
return render(request, 'format_example.html', {
'formatted_date': formatted_date,
'formatted_number': formatted_number,
})
通过本章学习,你应该能够:
- 配置Django国际化
- 实现字符串翻译
- 处理动态内容翻译
- 使用本地化格式
怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!