这个问题已多次提出,但我想我是从不同的原因得到这个问题,或者至少我不知道它是如何相关的。
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())也会失败,所以我不知道发生了什么。
答案 0 :(得分:1)
问题是Child
的自定义构造函数。当ORM尝试检索结果时,重写的构造函数会阻止ORM传入列值以正确实例化实例。换句话说,ORM试图以列指定的顺序传递值,例如,
Child(id, date_created, parent)
,而自定义构造函数需要按以下顺序传递值:
Child(parent, . . .)
要解决此问题,请删除自定义构造函数并使用
instance = Child(parent=parent)
每当您想要使用父级初始化子项时。