Проверка уникальности внутри прародителя с помощью ManyToManyField

Я пытаюсь проверить модель с ManyToManyField, указывающей на родительскую модель, чтобы она была уникальной в модели прародителя. Это нормально, если у разных бабушек и дедушек есть внуки с одинаковыми именами, но у бабушек и дедушек не может быть двух внуков с одинаковыми именами.

Этот вопрос Обсуждается решение, если отношения ForignKeys , но здесь это не работает. GrandChild должен быть сохранен, прежде чем я смогу сослаться на родителей, чтобы проверить, является ли он уникальным в пределах GrandParent.

Поскольку родители не могут быть присоединены до тех пор, пока не существует GrandChild, как можно проверить уникальность GrandChild по отношению к GrandParent?

class GrandParent(models.Model):
    name = models.CharField(max_length=255)

class Parent(models.Model):
    name = models.CharField(max_length=255)
    grandparent = models.ForeignKey(GrandParent)

    class Meta:
        unique_together('name', 'GrandParent')    

class GrandChild(models.Model):
    name = models.CharField(max_length=255)
    parents = models.ManyToManyField(Parent)

    def validate_unique(self, exclude=None):
        # validate that GrandChild is unique within a given GrandParent

Я попытался добавить метод save() к методу внука.

def save(self, *args, **kwargs):
    grand_parent = self.parents.all()[0].grandparent
    grand_children = [child for child in parent.grandchild_set.all() for parent in grandparent.parent_set.all()]

    for grand_child in grand_children:
        if grand_child.name == self.name and grand_child != self:
            raise IntegrityError("must be unique")

Но это дало IntegrityError

ValueError: "<GrandChild: name>" needs to have a value for field "grandchild" before this many-to-many relationship can be used.

person Cohan    schedule 19.04.2017    source источник
comment
почему вы не можете проверить уникальность при вызове из метода сохранения? Вы можете сказать, что если дедушка и бабушка содержат родителя, который содержит внука с атрибутами x, y, z, он не будет уникальным, учитывая, что данные, переданные этому внуку, в настоящее время сохраняются, поэтому отклоните   -  person Ryan Castner    schedule 19.04.2017
comment
Я все еще сталкиваюсь с проблемой manytomany, когда экземпляр не существует, но мне нужен экземпляр для проверки его уникальности.   -  person Cohan    schedule 19.04.2017


Ответы (1)


person    schedule
comment
Я понимаю, как это может работать, но на данный момент я также пытаюсь выполнить модульные тесты на модели (и еще не начал реализовывать представления). Я также хотел бы, чтобы он был действителен для интерфейсов, отличных от только представлений. - person Cohan; 19.04.2017
comment
Я не думаю, что вы понимаете, как работает save(), он всегда вызывается при создании модели. Попробуйте просто сделать save(self, *args, **kwargs): raise ValidationError('Nope.') и GrandChild.objects.create(name='bob'), и вы получите ValidationError, представления — это всего лишь один из наиболее распространенных интерфейсов для создания объектов, поэтому я показывал вам, как это работает. Вы можете сделать GrandChild.objects.create(name='bob', grand_parent_id=GrandParent.objects.filter(name='foo')[0].pk), и это тоже сработает. - person Ryan Castner; 19.04.2017