Django中如何将created_at与JsonField内的hours_old整数进行比较?
解决方案
方法1:将时间间隔转换为总小时数进行比较
你需要把created_at到现在的时间间隔转换为总小时数(数值类型),再和settings__json__data__hours_old的整数值比较。利用Django的Extract函数提取时间间隔的epoch秒数,再除以3600得到小时数:
from django.db.models import ExpressionWrapper, F, FloatField from django.db.models.functions import Extract from django.utils import timezone Person.objects.annotate( # 计算created_at到现在的总小时数(浮点数) hours_past=ExpressionWrapper( Extract(timezone.now() - F('created_at'), 'epoch') / 3600, output_field=FloatField() ), hours_old=F('settings__json__data__hours_old') ).filter( hours_old__lt=F('hours_past') )
方法2:将小时数转换为时间间隔,直接比较日期
更高效的方式是把hours_old转换为时间间隔(秒数),然后判断created_at是否早于「当前时间减去该间隔」,这样避免计算小时数,直接利用日期索引:
from django.db.models import ExpressionWrapper, F, DurationField from django.utils import timezone Person.objects.annotate( # 将hours_old转换为Duration类型(小时数*3600秒) threshold=ExpressionWrapper( F('settings__json__data__hours_old') * 3600, output_field=DurationField() ) ).filter( # 筛选created_at <= 当前时间 - threshold,即已超过指定小时数 created_at__lte=timezone.now() - F('threshold') )
注意事项
- 方法2性能更优,因为数据库可以对
created_at字段的索引进行利用,无需计算每条记录的时间间隔小时数。 - 确保
settings__json__data__hours_old存储的是有效的整数值,否则可能出现类型转换错误。 - Django 3.2.5支持上述表达式和函数,无需额外依赖。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

