首页 > 解决方案 > Django - 从每个组的最新日期检索对象 - PersonPhoto

问题描述

我的数据库包含不同人的护照图像。就像是:

class Person(models.Model):
    pass

class PersonPhoto(models.Model):
    date_captured = models.DateField()
    person = models.ForeignKey(Person, null=False)

我想为每个人提取他最近拍摄日期的所有图像。因此,如果 A 人有 8 月 5 日、5 日、9 日、11 日、11 日的照片,而 B 人有 8 月 7 日、9 日、13 日、13 日、19 日、19 日的照片,那么我想为 A 人获取 8 月 11 日的两张照片,以及 B 人 8 月 19 日的两张照片。

我目前这样做的方式是:

specific_dates_queryset = Q()
for photo in PersonPhoto.objects.all().values('person_id').annotate(max_date=Max('date_captured')):
    specific_dates_queryset |= Q(person_id=photo["person_id"], date_captured=photo["max_date"])


for photo in PersonPhoto.objects.filter(specific_dates_queryset).order_by("person_id"):
    print(f"image for person {photo.person_id}, of date {photo.date_captured}")

这个想法是首先找到每个人的照片的最新日期,然后在一个新的查询中从这些日期为这些人获取这些图像。

是否有更简单的解决方案可以在数据库中完成所有操作并避免冗余查询和数据获取?

标签: pythonpython-3.xdjangodjango-modelsdjango-queryset

解决方案


在单个查询中执行此操作的一种简单方法是使用相关人员的最新日期注释每张照片,然后按注释进行过滤。PersonPhoto这应该在查询集中返回所有需要的

from django.db.models import Max, F

PersonPhoto.objects.annotate(
   latest=Max('person__personphoto__date_captured')
).filter(
    date_captured=F('latest')
)

我不确定由于注释的性能如何,这可能取决于您使用的数据库和数据的性质


推荐阅读