每个唯一属性值的最新查询集


class SwallowMigration(models.Model):
    swallow = models.ForeignKey(Swallow)
    date = models.DateTimeField(auto_now_add=True)
    coconuts_carried = models.IntegerField()

如何获得每次燕子的最新迁移?

当然。latest()只给我最近的条目。是否有一种方法(可能使用Aggregation with Max?)来获取另一个字段中某些值的每个实例的最新信息?

如果只有Swallow实例和只有最近迁移的日期就足够了,那么下面的代码应该可以满足您的要求:

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

来自结果查询集的每个Swallow实例将具有一个"latest_migration"属性,该属性将是相关对象的最大日期时间。

如果你确实需要SwallowMigration实例,它将花费你N+1个查询,其中N是Swallow实例的数量。类似下面的代码将为您完成这一工作,不过您将在每个对象上使用预取的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,你必须要么使用数据从它是或构造模型实例。

如果要频繁执行此代码,那么在最新的SwallowMigration中添加一个外键可能是值得的,这样您就可以使用select_related()在单个查询中轻松检索它们。您只需要确保在添加新的SwallowMigration实例时保持外键的更新。

嗯,我觉得你可以这样使用Max:

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

但是我不确定它对你有什么好处,因为你必须通过id获取所有迁移,然后将它们附加到Swallow。

最新更新