Django - 无法分配,必须是一个实例

时间:2017-01-08 02:33:41

标签: python django

这个问题已多次提出,但我想我是从不同的原因得到这个问题,或者至少我不知道它是如何相关的。

Django:1.10.5,Python:3.5.2,Postgres:9.5

所以,我有这样的模型(简化):

class Parent(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    date_created = models.DateTimeField(auto_now=True)

class Child(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    date_created = models.DateTimeField(auto_now=True)
    parent = models.ForeignKey(Parent)

    def __init__(self, parent, *args, **kwargs):
        super(Child, self).__init__(*args, **kwargs)
        self.parent = parent

我有一个自定义查询集:

class ChildQuerySet(models.query.QuerySet):

    def find_recent(self):
        return self.order_by('-date_created')

Child.objects = ChildQuerySet.as_manager()

然后,我尝试为子项测试一些自定义查询集方法:

class ChildQuerysetDatabaseIntegrationTest(TestCase): # from django.test
    default_parent = Parent()

    def setUp(self):
        super(ChildQuerysetDatabaseIntegrationTest, self).setUp()
        self.default_parent.save()

    def test_find_recent(self):
        # given
        for _ in range(1, 10):
            child = Child(self.default_parent)
            child.save()

        # when
        recent = Child.objects.find_recent()
        ordered = Child.objects.order_by('-date_created')

        # then
        self.assertEqual(list(ordered), list(recent))

这会在最后一行测试中产生以下错误(获取所有实体):

ValueError: Cannot assign "UUID('...')": "Child.parent" must be a "Parent" instance.

通常,当出现一些映射错误时,在实体保存期间会抛出错误,但这里所有内容似乎都会成功保留,但在检索时失败。

试图分配给父实例的UUID对象实际上是孩子的id对象,这让我更加困惑。

我尝试将对象创建更改为Parent.objects.create(),但结果没有改变。调用任何检索Child对象的函数(如ordered.first())也会失败,所以我不知道发生了什么。

1 个答案:

答案 0 :(得分:1)

问题是Child的自定义构造函数。当ORM尝试检索结果时,重写的构造函数会阻止ORM传入列值以正确实例化实例。换句话说,ORM试图以列指定的顺序传递值,例如,

 Child(id, date_created, parent)

,而自定义构造函数需要按以下顺序传递值:

 Child(parent, . . .)

要解决此问题,请删除自定义构造函数并使用

 instance = Child(parent=parent)

每当您想要使用父级初始化子项时。