这是我的模型:
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
表中使用element_owner
和approver
显示子元素。
起初,我在不使用prefetch_reced的情况下执行许多关系,但事实证明这非常低效。直到我需要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以下错误返回:
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
模型名称。
我不知道为什么会发生这种情况,以及我能做什么来解决它。我正在使用MySQL数据库使用Django 1.9和Python 3.6。
这里的问题是您已声明
elements = models.ManyToManyField(
Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'))`
但是,当您将'elements'
传递给Prefetch
时,这是完全正确的它确定这与元素模型有关,而不是您预期的elementset2lement(是的,它确实很聪明(。因此,元素的向后字段名称是elementworkingset
,因为您尚未通过related_query_name
或models.ManyToManyField
中的related_name
声明其他字段。然后,您通过ElementSet2Element
QuerySet,Django尝试在其中找到elementworkingset
。由于您在ElementSet2Element
中没有这样的领域,因此失败了。
因此,您应该将'elementset2element_set'
传递给Prefetch
'elements'