Django ORM:仅允许设置一个字段(NOT NULL)

时间:2019-02-22 07:43:46

标签: django django-orm

对于M2M关系,我有以下穿透表:

class ContentOnPage(models.Model):

    objects = ContentOnPageModelManager()

    page = models.ForeignKey('Page', on_delete=models.CASCADE)
    video = models.ForeignKey('Video', null=True, on_delete=models.CASCADE)
    audio = models.ForeignKey('Audio', null=True, on_delete=models.CASCADE)
    text = models.ForeignKey('Text', null=True, on_delete=models.CASCADE)
    order_nbr = models.PositiveIntegerField(default=0)

对于videoaudiotext字段,我需要以下约束-一行中应严格存在1个非空值。我该如何实现?

2 个答案:

答案 0 :(得分:1)

您可以在保存实例之前对其进行检查,如果不符合要求,请提高ValidationError

def save(self, *args, **kwargs):
    all_values = [self.video, self.audio, self.text]
    not_null_values = [v for v in all_values if v]
    if len(not_null_values) == 1:
        super(ContentOnPage, self).save(*args, **kwargs)
    else:
        raise ValidationError

答案 1 :(得分:0)

也可以重写clean方法来检查是否满足约束条件:

#models.py
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError

def clean(self):
    contents = [value is not None for value in [self.video, self.audio, self.text]]
    if contents.count(True) != 1:
        raise ValidationError(_("Only one of the following fields has to be set: video, audio, text"))