当前位置: 首页 > article >正文

每天40分玩转Django:Django国际化

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,
    })

通过本章学习,你应该能够:

  1. 配置Django国际化
  2. 实现字符串翻译
  3. 处理动态内容翻译
  4. 使用本地化格式

怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!


http://www.kler.cn/a/451244.html

相关文章:

  • 【数据库原理】数据增删改查,DML、单表查询、多表连接查询
  • 2. SQL窗口函数使用
  • Linux网络——网络基础
  • VIVO Android面试题及参考答案
  • Windows开启IIS后依然出现http error 503.the service is unavailable
  • 项目亮点案例
  • 【Kibana01】企业级日志分析系统ELK之Kibana的安装与介绍
  • 学习一下USB DFU
  • AI驱动的数据分析:利用自然语言实现数据查询到可视化呈现
  • 2.在 Vue 3 中使用 ECharts 实现动态时间轴效果
  • Android Studio打开一个外部的Android app程序
  • embeding 层到底是什么
  • YOLOv8 引入高效的可变形卷积网络 DCNv4 | 重新思考用于视觉应用的动态和稀疏算子
  • 【hackmyvm】BlackWidow靶机wp
  • MongoDB教程002:文档(表)的增删改查
  • 如何在防火墙上指定ip访问服务器上任何端口呢
  • websocket再项目中的使用
  • java提高正则处理效率
  • Unity3D 控制Spine刷新率详解
  • Linux xargs 命令使用教程
  • nginx—rewrite功能
  • SQL中的约束
  • 数据库管理系统——NoSQL之文档数据库(MongoDB)
  • WEB UI 创建视图
  • 单片机:实现定时器中断(数码管读秒+LED闪烁)(附带源码)
  • 顶顶通呼叫中心中间件mod_cti模块安全增强,预防盗打风险(mod_cti基于FreeSWITCH)