我想尽量减少我的应用程序所做的数据库查询的数量,并且我更熟悉Django的ORM。我想知道,执行查询的情况是什么。
例如,这种格式与我正在寻找的答案一致(例如,目的,据我所知不准确):
我假设curried过滤操作永远不会发出额外的请求,但是从文档中看起来像filter()确实会产生数据库请求,如果它是第一个被调用的东西。
答案 0 :(得分:2)
请参阅Django关于何时评估查询集的文档:https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated
在这种情况下评估意味着执行查询。这主要发生在您尝试访问结果时,例如。在其上调用list()
或len()
或迭代结果时。
get()
不返回查询集而是返回模型对象,因此会立即对其进行求值。
答案 1 :(得分:2)
如果您正在使用测试用例,则可以使用django TestCase
中包含的自定义断言:assertNumQueries()。
示例:
with self.assertNumQueries(2):
x = SomeModel.objects.get(pk=1)
y = x.some_foreign_key_in_object
如果预期的查询数量错误,您会看到表单中的断言失败消息:
Num queries (expected - actual):
2 : 5
在此示例中,即使没有显式查询(get,filter,exclude等),外键也会导致其他查询。
出于这个原因,我会使用一种实用的方法:测试或记录,而不是尝试学习django应该查询的每种情况。
如果你不使用单元测试,你可以使用这个打印django发送的实际SQL语句的其他方法,这样你就可以了解查询的复杂性,而不仅仅是查询的数量: / p>
(DEBUG
设置必须设置为True
)
from django.db import connection
x = SomeModel.objects.get(pk=1)
y = x.some_foreign_key_in_object
print connection.queries
打印将显示查询字典:
[
{'sql': 'SELECT a, b, c, d ... FROM app_some_model', 'time': '0.002'},
{'sql': 'SELECT j, k, ... FROM app_referenced_model JOIN ... blabla ',
'time': '0.004'}
]
connection.queries
上的Docs。
当然,您也可以将两种方法结合使用,并在测试用例中使用print connection.queries
。