Почему использование .last() на различающемся наборе запросов дает мне объект, который не был первичным в запросе?

Bid.objects.all() дает мне два столбца с датой и значением ставки. Я хочу иметь только одну ставку на дату. Ставка должна быть наибольшим значением. Поэтому Bid.objects.all().order_by("date","bid_value").distinct("date") дает мне правильный порядок.

Но использование last не только берет последнюю строку из QuerySet, но и берет последний элемент из group_by, сделанный из distinct, что мне не нужно. Мне нужен только последний элемент набора запросов без изменения порядка.

Before distinct After distinct .last() .first()

1.Bid.objects.all()

2.Bid.objects.all().order_by("date","bid").distinct("date")

3.Bid.objects.all().order_by("date","bid").distinct("date").last()

но это должно дать мне 15.11.2022/50zł, а на самом деле

list(Bid.objects.all().order_by("date","bid").distinct("date").last())[-1]

дает мне соответствующий объект

4.Bid.objects.all().order_by("date","bid").distinct("date").first()

Как я могу использовать .last() / .first() - без преобразования в список. Потому что когда я использую list(Queryset), у меня есть правильные значения для последних объектов. Но замена queryset на list не является хорошим стандартом, я полагаю.

Вам нужно предложение GROUP BY.

На обычном SQL вы бы написали что-то вроде

SELECT bid_date, MAX(bid) 
FROM bids
GROUP BY bid_date 
ORDER BY bid_count DESC;

В Django вы можете использовать aggregations или annotations, но агрегатные предложения являются терминальными, тогда как если вы используете аннотации, они вернут QuerySet, на котором вы можете использовать вызовы first() и last().

Bid.objects \
.values('bid_date') \
.annotate(Max('bid_count')) \
.order_by('bid_count__max') \
.last()

Это полезная статья о группировке по запросам в Django: https://simpleisbetterthancomplex.com/tutorial/2016/12/06/how-to-create-group-by-queries.html

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