@Animkim
Питон вокруг меня

В чем отличие queryset от list?

ads = Ads.objects.all()
for ad in ads[:10] 
	pass

ads = ads[:10]
for ad in ads:
  pass

Поведение у этих двух for разное, слайсы работают в QuerySet как-то по другому, но как? В чем отличие?
  • Вопрос задан
  • 766 просмотров
Решения вопроса 1
winordie
@winordie
Лучшая документация -- исходники
Ясное дело по другому — ведь это же не список.
Давай посмотрим как он работает:
https://github.com/django/django/blob/master/djang...
def __getitem__(self, k):
        if not isinstance(k, (slice,) + six.integer_types):
            raise TypeError
        assert ((not isinstance(k, slice) and (k >= 0)) or
                (isinstance(k, slice) and (k.start is None or k.start >= 0) and
                 (k.stop is None or k.stop >= 0))), \
            "Negative indexing is not supported."

        if self._result_cache is not None:
            return self._result_cache[k]

        if isinstance(k, slice):
            qs = self._clone()
            if k.start is not None:
                start = int(k.start)
            else:
                start = None
            if k.stop is not None:
                stop = int(k.stop)
            else:
                stop = None
            qs.query.set_limits(start, stop)
            return list(qs)[::k.step] if k.step else qs

        qs = self._clone()
        qs.query.set_limits(k, k + 1)
        return list(qs)[0]

По моему тут все предельно ясно:
- передавать можно либо число, либо слайс
- при этом число или начальное и конечное значения слайса должны быть не меньше нуля
- если задан слайс — то делается копия текущего queryset'а и для объекта query копии устанавливаются low_mark и/или high_mark, которые в будующем превратятся в OFFSET и LIMIT запроса к бд.
- далее возможно два варианта:
* если шаг не задан — возвращается созданая копия queryset'а
* если же шаг задан — то превращаем queryset в список и к нему уже применяем шаг

При этом, если не был задан шаг, то ни одного запроса к бд выполнено не было.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы