通过 [] 访问元素的 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)
@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)