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

如何在Wagtail设置中添加语言切换界面实现本地化?

解决Wagtail设置本地化的语言切换与渲染问题

一、修复管理面板的语言切换功能

Wagtail默认设置界面为单实例设计,要实现多语言切换需调整模型约束并自定义视图与模板:

1. 调整模型唯一约束

修改CompanySettings的Meta类,合并站点、翻译键和语言的唯一约束,确保每个站点每个语言对应一个设置实例:

from django.utils.translation import gettext_lazy as _
from django.db import models
from wagtail.contrib.settings.models import BaseGenericSetting, register_setting
from wagtail.models import TranslatableMixin

@register_setting(icon="doc-full")
class CompanySettings(TranslatableMixin, BaseGenericSetting):
    top_services = models.CharField(
        _("Top Services"), max_length=250, blank=True, null=True, help_text="add top services separated by comma"
    )
    copyright_text = models.CharField(_("Copyright Text"), max_length=100, blank=True, null=True)

    panels = [
        FieldPanel('top_services'),
        FieldPanel('copyright_text')
    ]

    class Meta:
        unique_together = (('site', 'translation_key', 'locale'),)

2. 自定义支持多语言的视图集

创建视图集,实现根据请求语言加载对应设置实例,并传递语言列表到模板:

from wagtail.contrib.settings.views import BaseSettingViewSet
from wagtail.models import Locale

class TranslatableSettingViewSet(BaseSettingViewSet):
    def get_object(self):
        # 获取请求指定的语言,默认用当前激活语言
        locale_code = self.request.GET.get('locale', None)
        locale = Locale.objects.get(language_code=locale_code) if locale_code else Locale.get_active()
        
        # 获取或创建当前站点+语言的设置实例
        obj, created = self.model.objects.get_or_create(
            site=self.request.site,
            locale=locale,
        )
        return obj

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 传递所有可用语言和当前语言到模板
        context['available_locales'] = Locale.objects.all()
        context['current_locale'] = self.object.locale
        return context

注册设置时指定该视图集:

@register_setting(icon="doc-full", viewset=TranslatableSettingViewSet)
class CompanySettings(TranslatableMixin, BaseGenericSetting):
    # 模型代码同上

3. 自定义设置编辑模板

创建模板wagtailcontrib/settings/edit.html覆盖默认模板,添加语言切换下拉框:

{% extends "wagtailadmin/base.html" %}
{% load i18n wagtailadmin_tags %}

{% block titletag %}{% trans "Settings" %}: {{ setting_name }}{% endblock %}

{% block content %}
    {% trans "Settings" as settings_str %}
    {% include "wagtailadmin/shared/header.html" with title=settings_str subtitle=setting_name icon=icon %}

    <!-- 语言切换器 -->
    <div class="w-flex w-items-center w-mb-4">
        <label class="w-mr-2">{% trans "Language:" %}</label>
        <select id="locale-switcher" class="w-select">
            {% for locale in available_locales %}
                <option value="{{ locale.language_code }}" {% if locale == current_locale %}selected{% endif %}>
                    {{ locale.get_display_name }}
                </option>
            {% endfor %}
        </select>
    </div>

    <script>
        document.getElementById('locale-switcher').addEventListener('change', function() {
            const locale = this.value;
            const url = new URL(window.location);
            url.searchParams.set('locale', locale);
            window.location.href = url.toString();
        });
    </script>

    <div class="w-form">
        <form action="{% url view.edit_url_name %}" method="POST" novalidate>
            {% csrf_token %}
            {{ edit_handler.render_form }}

            <div class="w-form-actions">
                <button type="submit" class="w-button w-button--primary">{% trans "Save" %}</button>
            </div>
        </form>
    </div>
{% endblock %}

完成后,管理面板会显示语言切换下拉框,选择不同语言即可编辑对应版本的设置。


二、模板中本地化渲染设置

若暂时无需修改管理面板,可先通过代码创建多语言实例,再在模板中按需获取:

1. 批量创建多语言设置实例

通过Django Shell或数据迁移为每个语言创建实例:

from myapp.models import CompanySettings
from wagtail.models import Site, Locale

site = Site.objects.first()
locales = Locale.objects.all()

# 为每个语言初始化设置
for locale in locales:
    CompanySettings.objects.get_or_create(
        site=site,
        locale=locale,
        defaults={
            'top_services': "Web Design, Development" if locale.language_code == 'en' else "设计、开发",
            'copyright_text': "© 2024 My Company" if locale.language_code == 'en' else "© 2024 我的公司"
        }
    )

2. 模板中获取当前语言的设置

使用Wagtail的get_settings标签和TranslatableMixin的get_translation方法:

{% load wagtailsettings_tags %}

{% get_settings use_default_site=True %}
{% with localized_settings=company_settings.get_translation(request.Locale) %}
    <div class="top-services">{{ localized_settings.top_services }}</div>
    <div class="copyright">{{ localized_settings.copyright_text }}</div>
{% endwith %}

若当前语言无对应实例,get_translation会自动返回默认语言版本(可通过fallback=False关闭该行为)。

内容的提问来源于stack exchange,提问作者Imtiaz Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 00:40:20