Django Оценка QuerySet при доступе к элементам через [] - PullRequest
1 голос
/ 26 марта 2020
@pytest.mark.django_db
def test_cats(self): 
    CatFactory.create_batch(2)
    cats = Cat.objects.all()
    self.assertNotEqual(cats[0], cats[1])

Почему этот тестовый пример проходит? Является ли это одним из случаев, когда оценивается Django QuerySets (итерация, нарезка и т. Д. c.)?

1 Ответ

2 голосов
/ 26 марта 2020

Является ли это одним из случаев, когда Django QuerySets оценивается (итерация, нарезка и т. Д. c.)?

Подписание набора запросов целым числом (поэтому не срез) заставит оценку. Если набор запросов еще не оценен, он выполнит запрос для этого указанного c элемента. Так, например, в 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)
...