You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django按Person分组查询每个人员最新拍摄日期的所有PersonPhoto照片

你当前的方案会先拉取全量人员的最大拍摄日期到Python层拼接查询条件,存在两次数据库查询,同时数据量大时内存占用也很高,以下是两种仅执行单次数据库查询的实现方案,所有逻辑都在数据库层完成:

方案1:窗口函数实现(兼容性最优,Django 2.0+ 支持)

该方案通过给同人员的照片按拍摄日期倒序排名,直接筛选出排名第一的所有照片,自动覆盖同一最新日期下的多张照片场景:

from django.db.models import F, Window
from django.db.models.functions import Rank

# 给每个人员的照片按拍摄日期倒序排名,最新日期的照片排名都是1
latest_photos = PersonPhoto.objects.annotate(
    date_rank = Window(
        expression = Rank(),
        partition_by = F('person_id'),
        order_by = F('date_captured').desc()
    )
).filter(date_rank = 1).order_by('person_id')

# 直接遍历结果即可
for photo in latest_photos:
    print(f"image for person {photo.person_id}, of date {photo.date_captured}")

方案2:子查询实现(Django 1.11+ 支持)

如果你的Django版本不支持窗口函数,可以用子查询实现,性能和窗口函数方案一致:

from django.db.models import Max, OuterRef, Subquery

# 构造子查询:取对应人员的最大拍摄日期
latest_date_subq = PersonPhoto.objects.filter(
    person = OuterRef('person')
).values('person').annotate(
    max_date = Max('date_captured')
).values('max_date')[:1]

# 直接过滤出日期等于对应人员最新日期的照片
latest_photos = PersonPhoto.objects.filter(
    date_captured = Subquery(latest_date_subq)
).order_by('person_id')

额外场景:仅需每人最新1张照片(PostgreSQL专属)

如果你用的是PostgreSQL数据库,且不需要同一最新日期的多张照片,只要每人最新的1张,可以用更简洁的distinct语法:

latest_photos = PersonPhoto.objects.order_by(
    'person_id', '-date_captured'
).distinct('person_id')

内容的提问来源于stack exchange,提问作者user972014

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:51:03