我看到 QuerySet
类有 2 个不同的方法似乎服务于相同的目的(除非我弄错了):.__nonzero__
和 .exists
。 (是的,我知道 .__nonzero__
被 bool
使用。)
我的问题:如果这两种方法都只检查查询集中是否有任何对象,为什么它们有不同的实现?
Django 文档对 QuerySet.__nonzero__
说:
Note: Don't use this if all you want to do is determine if at least one result exists, and don't need the actual objects. It's more efficient to use exists() (see below).
(我没有在“下面”找到任何有见地的东西。)
为什么 QuerySet.__nonzero__
的实现效率不高?它是否试图实现与 .exists
不同的东西? Django 开发人员不执行 __nonzero__ = exists
的原因是什么?
最佳答案
Why does QuerySet.nonzero have a non-efficient implementation? Is it trying to achieve something different than .exists? What is the reason that the Django developers don't do nonzero = exists?
我认为这是因为 exists
仅在特定情况下有效。
想象一下如果 __nonzero__
具有“高效”实现的这种常见情况。
foos = Foo.objects.filter(bar='baz')
if foos: # nonzero() calls exists() which causes extra query
# even though the QS is already going to be evaluated
# which in my projects is a common pattern.
print "Yay for foos!"
for foo in foos:
print foo
__nonzero__
还评估查询并将结果存储在缓存中。这意味着所有结果都存储在内存中。
exists
只关心 1 行,甚至不实例化 django 对象,甚至不将其结果存储在缓存中。
如果您只是检查某物是否存在,而不以任何方式需要数据,这似乎很有用。
Why don't the devs make
__nonzero__
==exists
?
因为 exists
假定您不关心结果。如果 __nonzero__
调用 exists
,我们将没有结果。如果 exists
调用了 __nonzero__
,我们将收集结果(可能很多)只是为了检查一行是否存在。
例子:
bool( Foo.objects.filter(user=user) )
# calls __nonzero__, evaluates, converts all fields to python objects
# and stores in queryset._result_cache
Foo.objects.filter(user=user).exists()
# stores nothing, and query only returns one row.
# less data from DB and less python overhead generating django model instances.
关于python - Django: `QuerySet.__nonzero__` 和 `QuerySet.exists` 之间有什么区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14368205/