Django defer() 和 only() 查询集不起作用?

Posted

技术标签:

【中文标题】Django defer() 和 only() 查询集不起作用?【英文标题】:Django defer() and only() queryset not working? 【发布时间】:2021-05-29 13:08:54 【问题描述】:

如果我误解了查询集中 defer() 或 only() 的正确用法,请指导我。

这是我试图从 Donor 模型中仅获取选定字段数据以加快处理速度的代码,因为它有 2000 个条目,当我使用 all() 时,它需要时间来获取数据。

def donor(request):
        # donors = Donors.objects.all()
        donors = Donors.objects.only('donorid','donor_type','title','donor_name','address',
                                       'mobile_no','jamatkhana')
        # donors = Donors.objects.defer('donorid','donor_type','title','donor_name','address',
                                       'mobile_no','jamatkhana')
        return render(request,"hod_template/add_donor_template.html","donors":donors)

使用“only()”或“defer()”后,结果仍然与“all()”相同,没有一个选定的字段既不延迟也不延迟。甚至加载时间比 all() 还要多。

请告诉我如何从捐助者模型中仅获取这些选定的字段数据。我还告诉你我也尝试过“Values()”方法,但问题是“jamatkhana”字段是 ForeignKey,我也想要它的数据。但是使用“Values()”方法它只获取值而不是外键内部数据。 希望我解释清楚?

【问题讨论】:

.defer().only() 仍将提供相同的对象,但会推迟获取字段。如果您的模板仍然需要这些项目,它将进行额外的查询,因此加载这些项目可能需要额外的时间。 因此取决于您在模板中呈现的属性。 所以请渲染数据的模板部分。 .defer.only 也是彼此的对应物,因此它们包含相同的值列表是没有意义的。 我想问你真的需要在一页上显示2000个条目吗?我相信没有人能真正读懂……也许你应该使用分页? 【参考方案1】:

但问题是jamatkhana 字段是ForeignKey,我也想要它的数据。

可能获取ForeignKey 引用的相关对象是瓶颈。您可以使用.select_related(…) [Django-doc] 在数据库端创建JOIN,从而使用相同的查询获取相关jamatkhana 字段的数据。如果没有.select_related(…),它会进行额外的查询per Donor 来获取相关数据,因此这很容易导致对数据库的大量额外查询。

因此,您可以使用以下方式渲染它:

donors = Donors.objects<b>.select_related('jamatkhana')</b>

正如@AbdulAzizBarkat 指出的那样,通常pagination 用于减少从网络服务器到客户端的数据量,并且通常通过对查询集进行切片,您还可以减少带宽(有时还会减少查询数量)从数据库到 Django/Python 层。

【讨论】:

以上是关于Django defer() 和 only() 查询集不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Django面试集锦(1-50)

Django 07

085:QuerySet API详解-defer和only

ORM数据库查询优化only与defer(select_related与prefetch_related)

django功能六

django功能六