如何通过Django ORM获取多模型的最新创建/修改时间?
Django多模型最新操作时间戳优化方案
问题1:用Django ORM简化多模型最新创建时间的获取
可以通过ORM的annotate+union组合实现,完全在数据库层面计算最大值,避免Python端的繁琐迭代:
from django.db.models import Max # 定义各模型的查询集(保留原有过滤条件) querysets = [ Model_1.objects.all().annotate(latest_created=Max('created')).values('latest_created'), Model_2.objects.filter(active=True).annotate(latest_created=Max('created')).values('latest_created'), Model_3.objects.filter(active=True).annotate(latest_created=Max('created')).values('latest_created'), ] # 合并所有查询集并取全局最大值 combined_queryset = querysets[0].union(*querysets[1:]) last_created = combined_queryset.aggregate(max_time=Max('latest_created'))['max_time']
这种方式直接通过SQL的UNION合并各模型的最大创建时间,再取全局最大值,性能优于原代码的Python端迭代计算。
问题2:扩展对比modified字段,获取全局最新操作时间
要同时考虑created(新对象创建)和modified(已有对象修改)的时间,可使用Django的Greatest函数,先计算每个模型内两个字段的最大值,再取全局最大值:
from datetime import datetime from django.db.models import Max, Value, DateTimeField from django.db.models.functions import Greatest, Coalesce # 定义各模型的查询集,计算每个模型的最新操作时间(created和modified的最大值) querysets = [ Model_1.objects.all() .annotate( latest_op=Coalesce( Greatest(Max('created'), Max('modified')), Value(datetime.min, output_field=DateTimeField()) ) ) .values('latest_op'), Model_2.objects.filter(active=True) .annotate( latest_op=Coalesce( Greatest(Max('created'), Max('modified')), Value(datetime.min, output_field=DateTimeField()) ) ) .values('latest_op'), Model_3.objects.filter(active=True) .annotate( latest_op=Coalesce( Greatest(Max('created'), Max('modified')), Value(datetime.min, output_field=DateTimeField()) ) ) .values('latest_op'), ] # 合并查询集并取全局最新操作时间 combined_queryset = querysets[0].union(*querysets[1:]) last_operation = combined_queryset.aggregate(max_time=Max('latest_op'))['max_time']
Greatest函数用于在单个模型内取created和modified的最大值Coalesce用于处理模型无数据的情况(返回一个极小值,避免Max计算时忽略该模型)- 最终通过
union合并所有模型的结果,再取全局最大值
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

