带有M2M字段的模型clean()中的Django验证不能用于创建

时间:2018-01-11 15:30:47

标签: python django

如何处理暗示M2M字段的模型验证?

例如,

class Object1
    objects_2 = models.ManyToManyField(Object2)

    def clean():
        # any operation implying objects_2 field.
        # for example: if self.objects_2.exists() ...

这适用于非更新,但在对象创建时,我会遇到此错误:"<Object1>" needs to have a value for field "id" before this many-to-many relationship can be used.

我理解这个错误,但在这种情况下你会如何做出正确的验证呢?

我目前的解决方法是,如果用户正在创建Object1实例,则从表单中删除objects_2字段,并强制用户编辑Object1实例以更改该字段。 太可怕了吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

django-modelcluster允许在将相关模型保存到数据库之前使用它们。它有一个ParentalManyToManyField,它为多对多关系提供了一些优势,但正如在README中所说,在开始将它们添加到Object1之前,子对象(Object2实例)必须存在于数据库中。 / p>

相反,您可以使用django-modelcluster的ParentalKey关系,并手动填充直通表:

from django.db import models
from django.core.exceptions import ValidationError
from modelcluster.models import ClusterableModel
from modelcluster.fields import ParentalKey


class Object2(ClusterableModel):
    name = models.CharField(max_length=255)


class ObjectThroughModel(models.Model):
    object_1 = ParentalKey('Object1', related_name='through_model')
    object_2 = ParentalKey('Object2', related_name='through_model')


class Object1(ClusterableModel):
    name = models.CharField(max_length=255)

    def clean(self):
        for through_object in self.through_model.all():
            if self.name in through_object.object_2.name:
                raise ValidationError("Object 2 name cannot contain object 1's name")

这允许你这样做:

>>> o1 = Object1(name='hi')
>>> o1.through_model.add(ObjectThroughModel(object_2=Object2(name='hi2')))
>>> o1.clean()
ValidationError: ["Object 2 name cannot contain object 1's name"]