无法理解何时在 Django 中评估 QuerySets

having trouble in understanding when QuerySets are evaluated in django

考虑以下示例

data = Employee.objects.all()
for i in data:
   print i.name

根据我在这里的低估,它会在每个循环中访问数据库。我不确定天气我是对还是错。

下一个疑问是

data = Employee.objects.get(id=1)

在这种情况下,它什么时候会访问数据库?如果我将数据存储到另一个变量中怎么办?

如果我这样做了会怎样

data = Employee.objects.all()
data1 = []
data1 = data
for i in data1:
    print i

上面和这个有什么区别?

  1. 在您的第一种情况下,查询集被评估(因此访问数据库)once - 在循环开始时。
  2. get() 调用将立即访问数据库。将获取所有模型数据,并且在访问模型属性时不会访问数据库(除非它们是 ForeignKeys)。如果您将它存储在另一个变量中,则这些实例不会以任何方式链接。例如:

    var1 = Employee.objects.get(pk=1)
    var2 = Employee.objects.get(pk=1)
    
    var1.name = 'var1'
    var2.name = 'var2'
    var2.save()
    
    print var1.name
    >>> 'var1'
    

如果你想获取最新保存对象的版本,你可以调用refresh_from_db()方法

    var1.refresh_from_db()
    var1.name
    >>> 'var2'
  1. 1) 和 3) 之间没有区别,因为在 3) 中您只需通过 data1 变量使查询集可访问。它不会在分配时进行评估,但会在迭代时进行评估。
  1. 在第一种情况下,它将在 for 循环开始时访问数据库,更准确地说是在第一个循环中。

  2. 第二个,它还不会访问数据库,因为 QuerySet 还没有被评估。 QuerySet 是惰性的,在以下情况下进行评估:

  • The first time you iterate over them
  • When you slice them. for instance: Post.objects.all()[:3]
  • When you pickle or cache them
  • When you call repr() or len() on them
  • When you explicitly call list() on them
  • When you test it in a statement such as bool() , or , and , or if

来自书本Django by Example, p. 21

有关何时评估 QuerySet 的更多信息,请参阅 docs