通过 [] 访问元素的 Django QuerySet 评估

Django QuerySet evaluation on accessing elements via []

@pytest.mark.django_db
def test_cats(self): 
    CatFactory.create_batch(2)
    cats = Cat.objects.all()
    self.assertNotEqual(cats[0], cats[1])

为什么这个测试用例通过了?这是对 Django QuerySet 进行评估(迭代、切片等)的情况之一吗?

Is this one of the cases when Django QuerySets get evaluated (iteration, slicing, etc.)?

使用整数(而不是切片)为查询集下标将强制求值。如果尚未评估查询集,它将对该特定元素进行查询。因此,例如在 MySQL 中,它将进行两个如下所示的查询:

SELECT *
FROM cat
LIMT 1
OFFSET 0

SELECT *
FROM cat
LIMT 1
OFFSET 1

默认情况下,两个 Model 对象被认为是相同的,因为这两个项目来自同一模型,并且具有相同的主键。

然而,以上并不是很安全,因为数据库不保证任何顺序。如果在两个查询之间修改了数据库,则可能会返回相同的 Cat。您可能想在此处添加 .order_by('pk')

然而,通过切片进行评估可能会更好,例如:

@pytest.mark.django_db
def test_cats(self): 
    CatFactory.create_batch(2)
    <b>cat0, cat1</b> = Cat.objects.all()[:2]
    self.assertNotEqual(cat0, cat1)