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

如何在Django Parler中实现各语言内标题唯一?

解决django-parler多语言环境下标题按语言唯一的问题

问题背景

使用django-parler实现多语言模型时,尝试给波兰语添加与英文相同的标题“Sport”,无论从管理面板操作还是加载fixture都会报错,提示标题已存在。排查发现是因为TranslatedFields中的title字段设置了unique=True——这个约束是全局生效的,而非按语言维度限制。需要实现同语言内标题唯一,但不同语言允许使用相同标题的需求。

相关代码参考

  • 初始错误模型代码:
translations = TranslatedFields(
    title=models.CharField(_('Title'), unique=True, max_length=40, null=False, blank=False)
)
  • django-parler配置:
PARLER_LANGUAGES = {
    None: (
        {'code': 'en',}, # English
        {'code': 'pl',}, # Polish
        {'code': 'uk',}, # Ukrainian
    ),
    'default': {
        'fallbacks': ['en'],
        'hide_untranslated': False,
    }
}
  • 当前模型(已移除全局unique约束):
class InterestsGroup(TranslatableModel):
    '''
    Group for storing similar interests (that are related to same topic)
    '''
    translations = TranslatedFields(
        title=models.CharField(_('Title'), unique=False, max_length=40, null=False, blank=False)
    )

    class Meta:
        verbose_name = _('Interests Group')
        verbose_name_plural = _('Interests Groups')
        ordering = ['id'] 

解决方案

1. 确保移除全局唯一约束

先确认TranslatedFields里的title字段已经设置unique=False(或直接省略该参数,默认值为False),避免全局唯一的限制。

2. 添加按语言维度的联合唯一约束

django-parler自动生成的翻译表会包含language_code字段,我们需要给翻译表添加title和language_code的联合唯一约束,通过TranslationsMeta类来配置翻译表的元数据:

方式一:使用unique_together(兼容旧版Django)

from django.db import models
from parler.models import TranslatableModel, TranslatedFields

class InterestsGroup(TranslatableModel):
    '''
    Group for storing similar interests (that are related to same topic)
    '''
    translations = TranslatedFields(
        title=models.CharField(_('Title'), max_length=40, null=False, blank=False)
    )

    class Meta:
        verbose_name = _('Interests Group')
        verbose_name_plural = _('Interests Groups')
        ordering = ['id'] 

    class TranslationsMeta:
        # 配置翻译表的联合唯一约束:同一语言下标题唯一
        unique_together = (('title', 'language_code'),)

方式二:使用UniqueConstraint(Django 2.2+推荐)

from django.db import models
from parler.models import TranslatableModel, TranslatedFields

class InterestsGroup(TranslatableModel):
    '''
    Group for storing similar interests (that are related to same topic)
    '''
    translations = TranslatedFields(
        title=models.CharField(_('Title'), max_length=40, null=False, blank=False)
    )

    class Meta:
        verbose_name = _('Interests Group')
        verbose_name_plural = _('Interests Groups')
        ordering = ['id'] 

    class TranslationsMeta:
        constraints = [
            models.UniqueConstraint(
                fields=['title', 'language_code'],
                name='unique_title_per_language'
            )
        ]

3. 应用数据库迁移

修改模型后,执行以下命令生成并应用迁移,让数据库层面的约束生效:

python manage.py makemigrations
python manage.py migrate

这样配置后,同一语言(如英文)下不能有重复的title,但不同语言(如英文和波兰语)可以同时使用“Sport”作为标题,完全满足需求。

内容的提问来源于stack exchange,提问作者Yulian Rudenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:11:05