使用ManyToManyField验证祖父母中的唯一性

时间:2017-04-19 15:38:26

标签: django django-models manytomanyfield

我试图验证指向父模型的ManyToManyField模型在祖父模型中是唯一的。如果不同的祖父母有同名的孙子女,那就没事了,但是祖父母可能没有两个同名的孙子。

This question如果关系为ForignKey,则讨论解决方案,但这不起作用。在我引用父母进行测试以确定它是否在GrandParent中是唯一的之前,必须保存GrandChild。

由于在GrandChild存在之前不能附加父母,如何针对GrandParent验证GrandChild的唯一性?

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.

1 个答案:

答案 0 :(得分:0)

def save(self, *args, **kwargs):
    grand_parent_id = kwargs.pop('grand_parent_id')
    if grand_parent_id is None:
        raise SomeException(...)
    grand_parent = GrandParent.objects.get(pk=grand_parent_id)
    for parent in grand_parent.parent_set.all():
        for grand_child in parent.grandchild_set.all():
           if grand_child.name == self.name:
               raise IntegrityError("Name must be unique")

# views.py
grand_parent = get_object_or_404(GrandParent, pk=kwargs.get('grand_parent_pk'))
if form.is_valid():
    form.save(grand_parent_id=grand_parent.pk)