LinkData.objects.all().order_by('-id')[0]
- это не набор запросов, это объект модели, поэтому ваша ошибка.
Вы можете попробовать LinkData.objects.all().order_by('-id')[0:1]
, который действительно является QuerySet, но он не будет работать. Учитывая, как работает prefetch_related
, аргумент queryset должен возвращать набор запросов, который содержит все необходимые записи LinkData
(затем происходит дополнительная фильтрация, и элементы в нем объединяются с объектами LinkTarget). Этот набор запросов содержит только один элемент, так что это бесполезно. (И Django будет жаловаться «Не удается отфильтровать запрос после того, как будет взят фрагмент» и вызовет исключение, как и должно быть).
Давайте вернемся. По сути, вы задаете вопрос об агрегации / аннотации - для каждого LinkTarget вы хотите знать самый последний объект LinkData или «max» столбца «id». Самый простой способ - просто аннотировать идентификатор, а затем выполнить отдельный запрос, чтобы получить все объекты.
Итак, это будет выглядеть так (я проверил аналогичную модель в моем проекте, поэтому она должна работать, но код ниже может иметь некоторые опечатки):
linktargets = (LinkTargets.objects
.filter(dashboard=True)
.annotate(most_recent_linkdata_id=Max('linkdata_set__id'))
# Now, if we need them, lets collect and get the actual objects
linkdata_ids = [t.most_recent_linkdata_id for t in linktargets]
linkdata_objects = LinkData.objects.filter(id__in=linkdata_ids)
# And we can decorate the LinkTarget objects as well if we want:
linkdata_d = {l.id: l for l in linkdata_objects}
for t in linktargets:
if t.most_recent_linkdata_id is not None:
t.most_recent_linkdata = linkdata_d[t.most_recent_linkdata_id]
Я намеренно не превратил это в предварительную выборку, маскирующую linkdata_set
, потому что в результате у вас есть объекты, которые вам лгут - атрибут linkdata_set
теперь пропускает результаты. Вы действительно хотите быть укушенным этим где-нибудь в будущем? Лучше всего сделать новый атрибут, который имеет именно то, что вы хотите.