优化Django查询,其中它在与select\u相关的查询上使用与prefetch\u相关的查询

优化Django查询,其中它在与select\u相关的查询上使用与prefetch\u相关的查询,django,postgresql,Django,Postgresql,我试图找出如何优化Django查询。我有一个包含练习外键的查询集。该表引用了许多其他表。如果选择练习,我会使用prefetch\u related将它们包括在查询中,但我不知道在这种情况下如何执行,因为我是从不同的表执行的。目前,它被选为 super().get_queryset(request).select_related('exercise').prefetch_related('exercise__equipments', 'exercise__injuries') 但我不知道如何附加

我试图找出如何优化Django查询。我有一个包含
练习
外键的查询集。该表引用了许多其他表。如果选择
练习
,我会使用
prefetch\u related
将它们包括在查询中,但我不知道在这种情况下如何执行,因为我是从不同的表执行的。目前,它被选为

super().get_queryset(request).select_related('exercise').prefetch_related('exercise__equipments', 'exercise__injuries')
但我不知道如何附加
预取相关的
。考虑到这一点,我找到了一个解决方案:

return super().get_queryset(request).select_related(
    Prefetch(
        'exercise',
        queryset=Exercise.objects.prefetch_related('equipments', 'inuries')
    )
)
但是由于
'Prefetch'对象没有属性“split”
(我通过源代码跟踪了该属性),它失败了,而且看起来
select\u related
无法使用
Prefetch

编辑:更多信息:

  • 我正在尝试使用
    sortableStackedLine
  • 起始模型是模板

最终目标是优化从模板到设备/伤害的查询

也许这个示例会有所帮助。看看我是如何通过外键导航的 我的目标是得到一份有SkillName=“DJANGO”技能的简历

恢复-->恢复技能.Skill-->技能.SkillName

注意django如何处理cammel案例

Resume.objects.filter(resumeskill__Skill__SkillName="DJANGO")

如果我理解的很好,您希望使用select_相关和prefetch_相关的组合来优化查询

Prefetch
应与
Prefetch\u related
not
select\u related
一起使用

我不确定,因为我没有测试,试试这个

-代码如下:

prefetch1 = Prefetch(
    "exercise__equipments",
    queryset=Equipment.objects.all(), ----------------------------------- [2]
    to_attr="prefetch_equipments_set"
) ----------------------------------------------------------------------- [1]

prefetch2 = Prefetch(
    "exercise__injuries",
    queryset=Injury.objects.all(),    ----------------------------------- [2]
    to_attr="prefetch_injuries_set"
) ----------------------------------------------------------------------- [1]

queryset = Template.objects.all()  -------------------------------------- [2]
queryset = queryset.select_related("exercise")  ------------------------- [3]
queryset = queryset.prefetch_related(prefetch1, prefetch2)  ------------- [4]
  • [1]
    -
    预取对象
  • [2]
    -您可以添加
    过滤器
    订单
    任何内容
  • [3]
    -使用
    选择相关的
    优化查询
  • [4]
    -使用
    预取相关的
    [1]
    优化查询
-如何使用:

prefetch1 = Prefetch(
    "exercise__equipments",
    queryset=Equipment.objects.all(), ----------------------------------- [2]
    to_attr="prefetch_equipments_set"
) ----------------------------------------------------------------------- [1]

prefetch2 = Prefetch(
    "exercise__injuries",
    queryset=Injury.objects.all(),    ----------------------------------- [2]
    to_attr="prefetch_injuries_set"
) ----------------------------------------------------------------------- [1]

queryset = Template.objects.all()  -------------------------------------- [2]
queryset = queryset.select_related("exercise")  ------------------------- [3]
queryset = queryset.prefetch_related(prefetch1, prefetch2)  ------------- [4]
  • 从模板获取设备(id=1)
  • 从模板中获取伤害(id=1)

你能提供一个模型吗。py@bazzuk123添加了它们。这与过滤无关;我知道怎么做。我试图找出如何优化查询。通常它与
select_-related
prefetch_-related
一起使用,但驼峰案例在这里不适用于
prefetch_-related
。我会再次更新这个问题。不幸的是,它不起作用,但也可能是因为它的使用方式。我们不是直接调用queryset,而是在管理页面中使用它,所以我们需要调用它。我将
删除到了\u attr
,这样它就可以映射到基本attr,但仍然和以前一样多的查询:/n最终要获取哪些数据?我想优化查询,最终能够在一个查询中获取所有数据。现在,由于它是一个管理页面,需要打几十个电话,这显然需要时间。你能提供完整的管理代码吗?
prefetch1 = Prefetch(
    "exercise__equipments",
    queryset=Equipment.objects.all(), ----------------------------------- [2]
    to_attr="prefetch_equipments_set"
) ----------------------------------------------------------------------- [1]

prefetch2 = Prefetch(
    "exercise__injuries",
    queryset=Injury.objects.all(),    ----------------------------------- [2]
    to_attr="prefetch_injuries_set"
) ----------------------------------------------------------------------- [1]

queryset = Template.objects.all()  -------------------------------------- [2]
queryset = queryset.select_related("exercise")  ------------------------- [3]
queryset = queryset.prefetch_related(prefetch1, prefetch2)  ------------- [4]
queryset.get(id=1).exercise.prefetch_equipments_set
queryset.get(id=1).exercise.prefetch_injuries_set