解析 ManyToMany 关系时 django Prefetch() 的字段错误
Field error for django Prefetch() while resolving ManyToMany relations
这是我的模型:
class Element(models.Model):
name = models.CharField(max_length=255)
creator = models.ForeignKey(User, related_name='element_creator', on_delete=CASCADE)
element_type = models.ForeignKey('ElementType', on_delete=CASCADE)
create_date = models.DateTimeField(auto_now_add=True)
modif_date = models.DateTimeField()
description = models.TextField(blank=True, null=True)
class Meta:
managed = True
class ElementWorkingSet(models.Model):
name = models.CharField(max_length=255)
owner = models.ForeignKey(User, on_delete=CASCADE)
create_date = models.DateTimeField(auto_now_add=True)
modif_date = models.DateTimeField(auto_now=True)
project = models.ForeignKey(Project, on_delete=CASCADE)
active = models.BooleanField(default=True)
elements = models.ManyToManyField(Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'),
)
class Meta:
managed = True
class ElementSet2Element(models.Model):
element_working_set = models.ForeignKey('ElementWorkingSet',
on_delete=CASCADE)
elements = models.ForeignKey(Element, on_delete=CASCADE)
active = models.IntegerField()
element_owner = models.ForeignKey(User, on_delete=CASCADE)
approver = models.ForeignKey(User, null=True, related_name='+', on_delete=CASCADE)
class Meta:
managed = True
我正在提取 ElementWorkingSet 列表,并希望显示 ElementSet2Element
table 中具有 element_owner
和 approver
的子元素。
起初,我在不使用 prefetch_related 的情况下执行许多关系,但结果证明效率极低。在我需要 element_owner
和 approver
之前,响应时间还不错。但是提取这些字段使它变得非常慢。
我正在尝试修改我的查询,以使用以下查询执行更高效的查询:
query = ElementWorkingSet.objects.filter(
project__id=project_id, active=True).select_related(
'owner'
).prefetch_related(
Prefetch(
'elements',
queryset=ElementSet2Element.objects.select_related(
'elements',
'approver',
'element_owner'
),
),
)
问题是,Django returns 以下错误:
Cannot resolve keyword 'elementworkingset' into field. Choices are: active, approver, approver_id, id, element_owner, element_owner_id, element_working_set, element_working_set_id, elements, elements_id
我没有在任何地方使用 elementworkingset
作为变量。它实际上并没有发生在我的项目中的任何地方。调试后我注意到,它来自 ElementWorkingSet
型号名称。
我不知道为什么会这样,也不知道我能做些什么来解决它。我正在使用 Django 1.9 和 Python 3.6 以及 MySQL 数据库。
这里的问题是你声明了
elements = models.ManyToManyField(
Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'))`
这是完全正确的,但是,当您将 'elements'
传递给 Prefetch
时,
它确定这是与 Element 模型的关系,而不是您预期的 ElementSet2Element(是的,它做的事情非常聪明)。因此,Element 的向后字段名称是 elementworkingset
,因为您尚未在 models.ManyToManyField
(docs) 中通过 related_query_name
或 related_name
声明其他字段。然后你传递 ElementSet2Element
查询集,django 尝试在其中找到 elementworkingset
。由于您在 ElementSet2Element
中没有这样的字段,它失败了。
因此,您应该将 'elementset2element_set'
传递给 Prefetch
而不是 'elements'
这是我的模型:
class Element(models.Model):
name = models.CharField(max_length=255)
creator = models.ForeignKey(User, related_name='element_creator', on_delete=CASCADE)
element_type = models.ForeignKey('ElementType', on_delete=CASCADE)
create_date = models.DateTimeField(auto_now_add=True)
modif_date = models.DateTimeField()
description = models.TextField(blank=True, null=True)
class Meta:
managed = True
class ElementWorkingSet(models.Model):
name = models.CharField(max_length=255)
owner = models.ForeignKey(User, on_delete=CASCADE)
create_date = models.DateTimeField(auto_now_add=True)
modif_date = models.DateTimeField(auto_now=True)
project = models.ForeignKey(Project, on_delete=CASCADE)
active = models.BooleanField(default=True)
elements = models.ManyToManyField(Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'),
)
class Meta:
managed = True
class ElementSet2Element(models.Model):
element_working_set = models.ForeignKey('ElementWorkingSet',
on_delete=CASCADE)
elements = models.ForeignKey(Element, on_delete=CASCADE)
active = models.IntegerField()
element_owner = models.ForeignKey(User, on_delete=CASCADE)
approver = models.ForeignKey(User, null=True, related_name='+', on_delete=CASCADE)
class Meta:
managed = True
我正在提取 ElementWorkingSet 列表,并希望显示 ElementSet2Element
table 中具有 element_owner
和 approver
的子元素。
起初,我在不使用 prefetch_related 的情况下执行许多关系,但结果证明效率极低。在我需要 element_owner
和 approver
之前,响应时间还不错。但是提取这些字段使它变得非常慢。
我正在尝试修改我的查询,以使用以下查询执行更高效的查询:
query = ElementWorkingSet.objects.filter(
project__id=project_id, active=True).select_related(
'owner'
).prefetch_related(
Prefetch(
'elements',
queryset=ElementSet2Element.objects.select_related(
'elements',
'approver',
'element_owner'
),
),
)
问题是,Django returns 以下错误:
Cannot resolve keyword 'elementworkingset' into field. Choices are: active, approver, approver_id, id, element_owner, element_owner_id, element_working_set, element_working_set_id, elements, elements_id
我没有在任何地方使用 elementworkingset
作为变量。它实际上并没有发生在我的项目中的任何地方。调试后我注意到,它来自 ElementWorkingSet
型号名称。
我不知道为什么会这样,也不知道我能做些什么来解决它。我正在使用 Django 1.9 和 Python 3.6 以及 MySQL 数据库。
这里的问题是你声明了
elements = models.ManyToManyField(
Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'))`
这是完全正确的,但是,当您将 'elements'
传递给 Prefetch
时,
它确定这是与 Element 模型的关系,而不是您预期的 ElementSet2Element(是的,它做的事情非常聪明)。因此,Element 的向后字段名称是 elementworkingset
,因为您尚未在 models.ManyToManyField
(docs) 中通过 related_query_name
或 related_name
声明其他字段。然后你传递 ElementSet2Element
查询集,django 尝试在其中找到 elementworkingset
。由于您在 ElementSet2Element
中没有这样的字段,它失败了。
因此,您应该将 'elementset2element_set'
传递给 Prefetch
'elements'