Набор запросов Django для последнего из каждого уникального значения свойства - PullRequest
3 голосов
/ 17 апреля 2011
class SwallowMigration(models.Model):
    swallow = models.ForeignKey(Swallow)
    date = models.DateTimeField(auto_now_add=True)
    coconuts_carried = models.IntegerField()

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

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

Ответы [ 2 ]

3 голосов
/ 17 апреля 2011

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

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

Каждый экземпляр Swallow из полученногоqueryset будет иметь атрибут «latest_migration», который будет максимальным значением datetime для связанных объектов.

Если вам нужен экземпляр SwallowMigration, он будет стоить вам N + 1 запросов, где N - количествоГлотать экземпляры.Что-то вроде следующего будет делать для вас, хотя у вас будут объекты 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.

0 голосов
/ 17 апреля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...