В чем разница между возвратом 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. (Вы также легко можете сделать это со списком объектов, используя генератор или просто изменяя объекты).