gpt4 book ai didi

django - 过滤已评估的 QuerySet

转载 作者:行者123 更新时间:2023-12-01 01:25:47 26 4
gpt4 key购买 nike

我正在评估一个 QuerySet,然后是另一个,但第二个是第一个的子集。我试图以一种有效的方式做到这一点,尽可能少地调用数据库。 (之前有人问过这个问题,但老实说我并不完全理解答案,我不确定它们是否完全适用于我的想法。)

使用 Django 文档的 example Weblog models ,在一个 View 中,这是尝试优化之前的代码:

myblog = Blog.objects.get(pk=1)

d={} #going to pass this to my template

# not using count()
d['num_of_entries'] = len(myblog.entry_set.all())

# not using exists()
d['is_jolly'] = bool(Entry.objects.filter(blog=myblog, headline__startswith='Jolly'))

# ... other code but no further use of database in this view

第二个 QuerySet 是第一个的子集。我应该尝试使用纯 Python 来获取子集(因此只评估一个 QuerySet - 少一个数据库调用)?

或者,也许只是执行以下操作?
# other code as above

d['num_of_entries'] = myblog.entry_set.count()

d['is_jolly'] = Entry.objects.filter(blog=myblog, headline__startswith='Jolly').exists()

# ... other code but no further use of database in this view

最佳答案

“尽可能少的数据库查询”不是正确的标准。您还需要考虑这些数据库查询完成的工作量,以及从数据库传输到 Django 服务器的数据量。

让我们考虑两种实现您所追求的方法。方法一:

entries = myblog.entry_set.all()
num_of_entries = len(entries)
is_jolly = any(e.headline.startswith('Jolly') for e in entries)

方法二:
num_of_entries = myblog.entry_set.count()
is_jolly = Entry.objects.filter(blog=myblog, headline__startswith='Jolly').exists()

在方法 1 中有一个单一的数据库查询,但该查询将类似于 SELECT * FROM ENTRY WHERE ... .它可能会获取大量条目,并将其所有内容通过网络传输到您的 Django 服务器,然后该服务器将几乎所有这些内容都扔掉(它实际查看的唯一字段是 headline 字段)。

在方法 2 中有两个数据库查询,但第一个是 SELECT COUNT(*) FROM ENTRY WHERE ...它只获取一个整数,第二个是 SELECT EXISTS(...)它只获取一个 bool 值。由于这些查询不必获取所有匹配的条目,因此数据库有更多的可能性来优化查询。

因此,在这种情况下,方法 2 看起来要好得多,即使它发出更多查询。

关于django - 过滤已评估的 QuerySet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14269734/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com