以下是我的模特:
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列表,并希望在element_owner
表中显示带有approver
和ElementSet2Element
的子元素。
起初,我在不使用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返回以下错误:
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数据库。
答案 0 :(得分:0)
这里的问题是您已声明
elements = models.ManyToManyField(
Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'))`
但是,当您将'elements'
传递给Prefetch
时,这是完全正确的,
它确定这是与Element模型的关系,而不是你想象的ElementSet2Element(是的,它确实很聪明)。因此,元素的后向字段名称为elementworkingset
,因为您尚未在related_query_name
(docs)中通过related_name
或models.ManyToManyField
声明其他名称。然后你传递ElementSet2Element
queryset,django尝试在其中找到elementworkingset
。由于ElementSet2Element
中没有此类字段,因此失败。
因此,您应该将'elements'
传递给'elementset2element_set'
Prefetch