Django ORM: разрешить установку только одного поля (НЕ NULL) - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть следующая сквозная таблица для отношения 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)

И для полей video, audio и text я хочу следующее ограничение - должно быть строго 1, а не значение NULLв ряд.Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Метод 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"))
0 голосов
/ 22 февраля 2019

Вы можете проверить его перед сохранением своего экземпляра и поднять 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
...