2011-04-16 4 views
2
class SwallowMigration(models.Model): 
    swallow = models.ForeignKey(Swallow) 
    date = models.DateTimeField(auto_now_add=True) 
    coconuts_carried = models.IntegerField() 

Как я могу получить последнюю миграцию для каждой ласточки?Набор запросов Django для последнего из каждого уникального значения свойства

Конечно. Latest() дает мне самую последнюю запись. Есть ли способ (возможно, с помощью Aggregation with Max?), Чтобы получить последний для каждого экземпляра некоторого значения в другом поле?

ответ

-2

Хм я думаю, что вы можете использовать Макс, как это:

Swallow.objects.annotate(last_migration_id=Max('swallowmigration__pk')) 

Но я не уверен, что хорошо бы это сделать для вас, так как вы будете получать все миграции от ид, а затем прикрепить их Ласточка все равно.

+0

Это не обязательно приведет к последней миграции, только последняя вставляется в db. – shadfc

+0

Я предположил, что автор использовал последнюю(), что он может заказать их по id. –

+0

Я предполагаю, что поле «дата» имеет auto_now_add = True, тогда использование pk, вероятно, эквивалентно в этом случае, но не было бы во всех случаях (pk не является автоматическим приращением, кто-то искал авто- inc последовательность и т. д.). Общее решение должно основываться на поле «дата». – shadfc

2

Если только имея экземпляр Ласточка и только на дату последней миграции достаточно, следующий должен сделать это для вас:

Swallow.objects.annotate(latest_migration=Max('swallowmigration__date')) 

Каждый Ласточка экземпляр из полученного QuerySet будет иметь " last_migration ", который будет максимальным datetime из связанных объектов.

Если вам нужен экземпляр SwallowMigration, он будет стоить вам N + 1 запросов, где N - количество экземпляров Swallow. Что-то вроде следующего сделало бы это для вас, хотя у вас были бы объекты SwallowMigration с предварительно выбранным экземпляром Swallow для каждого, а не наоборот. Нетрудно обработать список и отменить их, установив экземпляр SwallowMigration в качестве атрибута экземпляра Swallow.

qs = SwallowMigration.objects.values(
    'swallow_id' 
).annotate(
    latest_migration=Max('date') 
) 
migrations = [] 
for vals in qs: 
    sm = SwallowMigration.objects.select_related(
     'swallow' 
    ).get(
     swallow=vals['swallow_id'], 
     date=vals['date'], 
    ) 
    migrations.append(sm) 

Там может быть (вероятно) способом вернуть все данные, которые вы хотите в одном запросе, но он должен быть сырой SQL и вам придется либо использовать данные, которые, как является или строит экземпляры модели из него.

Если этот код будет выполняться часто, возможно, стоит добавить внешний ключ в Swallow к последнему SwallowMigration, чтобы вы могли легко получить их в одном запросе с помощью select_related(). Вам просто нужно убедиться, что этот внешний ключ обновлен по мере добавления новых экземпляров SwallowMigration.

Смежные вопросы