Django上ManyToMany字段的唯一值
Posted
技术标签:
【中文标题】Django上ManyToMany字段的唯一值【英文标题】:Unique values across ManyToMany fields on Django 【发布时间】:2014-05-27 01:31:06 【问题描述】:我需要一些帮助来解决一个非常简单的问题(解释起来很简单,但不是为我解决)
我在 Django 中有以下模型:
class ClassGroup(models.Model):
group = models.CharField(_('group'), max_length=3)
course = models.ForeignKey(Course,
related_name='classgroups',
related_query_name='classgroup',
verbose_name=_('course'))
students = models.ManyToManyField(Actor,
related_name='student_classgroups',
related_query_name='student_classgroup',
verbose_name=_('student'))
lecturers = models.ManyToManyField(Actor,
related_name='lecturer_classgroups',
related_query_name='lecturer_classgroup',
verbose_name=_('lecturer'))
class Meta:
verbose_name = _('class group')
verbose_name_plural = _('class groups')
unique_together = ('group', 'course')
我需要添加一个约束,以防止 Actor 在每个 ClassGroup 中同时成为学生和讲师。是否可以在模型级别添加这样的约束?如果可能的话,我想避免上层基于表单/视图的解决方案。
非常感谢!
【问题讨论】:
【参考方案1】:我认为没有任何方法可以在 Django 的数据库级别指定它。您可以在模型的 clean()
或 validate_unique()
方法中检查这一点,但这些方法仅在特定情况下被调用。
一种方法是重组您的数据库,以便为学生和讲师使用一个表,并使用role
列进行区分。
class ClassGroup(models.Model):
group = models.CharField(_('group'), max_length=3)
course = models.ForeignKey(Course, related_name='classgroups',
related_query_name='classgroup',
verbose_name=_('course'))
actors = models.ManyToManyField(Actor, related_name='classgroups',
through='ClassRole')
class Meta:
verbose_name = _('class group')
verbose_name_plural = _('class groups')
unique_together = ('group', 'course')
class ClassRole(models.Model):
class_group = models.ForeignKey(ClassGroup, related_name='roles')
actor = models.ForeignKey(Actor, related_name='roles')
STUDENT_ROLE = 10
LECTURER_ROLE = 20
ROLE_CHOICES = (
(STUDENT_ROLE, _('student role')),
(LECTURER_ROLE, _('lecturer role')),
)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES)
在这种结构中,每个演员当然只有一个角色。您还可以编写自定义的Managers
和模型方法,以便轻松获取学生或讲师。
【讨论】:
非常感谢您的快速回答。你的解决方案无疑是非常好的,但是我和我的团队在我们的项目中处于先进的状态,所以我们希望避免模型更改,因为我们需要重构很多东西。但是,我们会检查是否有可能继续您的想法。如果不是,那么我认为我们将定义一个 clean() 方法(这实际上很糟糕,但我们没有更好的主意)。以上是关于Django上ManyToMany字段的唯一值的主要内容,如果未能解决你的问题,请参考以下文章
如何使 ManyToMany 字段的值显示在 Django 通用 DeleteView 中
Django ManyToMany 字段的 set() 操作是不是清除现有关系?