В чем разница между возвратом QuerySet или его списка?

Предположим, у меня есть две модели Book и User с внешним ключом на Book. И в одной из моих конечных точек API я возвращаю следующий QuerySet:

return User.objects.get(pk=user_id).posts.all()

Результат правильно отображается в браузере. Если я изменю строку на (используя список):

return list(User.objects.get(pk=user_id).posts.all())

... результат на выходе тот же.

Поскольку QuerySet является lazy-load (выполняется только при оценке), мой вопрос заключается в следующем:

Какова разница в памяти или производительности между этими двумя подходами? Или return и list будут иметь одинаковый эффект (оценка QuerySet)? Какой подход мне лучше использовать?

Я прочитал документацию, но мне не очень понятно, что происходит, когда возвращается QuerySet или его список.

Дополнительная информация: Я использую Ninja API, основанный на FastAPI, но вопрос будет таким же для контекстных данных представления django.

Заранее спасибо!

Вы можете создать другой кверисет из кверисета, применяя дополнительные фильтры.

qs = User.objects.get(pk=user_id).posts.all()

...

qs = qs.exclude( topic='brexit') # this is now an ex-topic.

Переработка списка в более короткий список требует больше усилий. Также неэффективно, если дальнейшая фильтрация включает охватывающие отношения в другие таблицы, объекты которых вы не предварительно отфильтровали. (т.е. проблема N+1).

Вы также можете расширить набор запросов, используя .union() и т.д.

С другой стороны, может быть полезно подать "аннотированный" кверисет в контекст шаблона, используя функцию генератора для связи соседних объектов.

def new_month_annotator( qs):
   month = '000000'
   for obj in qs.order_by('date')
       obj_month = obj.date.strftime('%Y%M')
       obj.new_month = (obj_month != month)
       yield obj
       month = obj_month

Если вы выполните итерацию в шаблоне, то теперь сможете легко генерировать метки месяцев в цикле forloop. (Вы также легко можете сделать это со списком объектов, используя генератор или просто изменяя объекты).

Вернуться на верх