在解决多托马尼关系时,django prefetch()的现场错误



这是我的模型:

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_ownerapprover显示子元素。

起初,我在不使用prefetch_reced的情况下执行许多关系,但事实证明这非常低效。直到我需要element_ownerapprover的时间为止,响应时间还不错。但是提取这些字段使其非常慢。

我正在尝试修改查询,通过使用以下查询来执行更有效的查询:

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_namemodels.ManyToManyField中的related_name声明其他字段。然后,您通过ElementSet2Element QuerySet,Django尝试在其中找到elementworkingset。由于您在ElementSet2Element中没有这样的领域,因此失败了。

因此,您应该将'elementset2element_set'传递给Prefetch

而不是'elements'

相关内容

  • 没有找到相关文章

最新更新