如何使用Django QuerySet按数据库日期字段筛选及解决相关报错
问题1:时区警告+日期筛选返回空结果解决
Django开启时区支持(settings.py中USE_TZ = True)时,你传入的日期字符串会被转换为不带时区信息的naive datetime,和数据库中存储的带时区datetime无法匹配,因此触发警告且返回空结果。
解决代码:
from django.utils import timezone import datetime # 方案1:用__date字段直接匹配日期部分,自动处理时区转换,适配按天查询场景 target_date = datetime.date(2021, 11, 26) result = Product.objects.filter(price_date__date=target_date) # 方案2:手动构造带时区的时间范围,适配需要精确控制时间区间的场景 from django.utils.timezone import make_aware start_time = make_aware(datetime.datetime(2021, 11, 26, 0, 0, 0)) end_time = make_aware(datetime.datetime(2021, 11, 27, 0, 0, 0)) result = Product.objects.filter(price_date__gte=start_time, price_date__lt=end_time)
问题2:CEST时区字符串验证错误解决
Django不识别CEST这类时区简写,需要将时间格式转换为符合要求的带标准偏移量/时区标识的格式,两种解决方式:
- 直接把时区简写替换为对应的UTC偏移量:把
2021-09-28 08:38:13 CEST改为2021-09-28 08:38:13+02:00(CEST对应UTC+2时区) - 先解析字符串为带时区的datetime对象再传入查询:
from dateutil import parser input_time_str = "2021-09-28 08:38:13 CEST" aware_dt = parser.parse(input_time_str).astimezone(timezone.get_default_timezone()) result = Product.objects.filter(price_date=aware_dt)
需求最终实现代码
1. 查询price_date为2021年11月26日的价格数据
直接使用问题1的两种方案即可,推荐使用__date字段的写法更简洁。
2. 筛选最新的30条价格数据
按price_date倒序排序后取前30条即可:
latest_30_records = Product.objects.order_by('-price_date')[:30]
内容的提问来源于stack exchange,提问作者lostAtom
相关产品推荐
相关产品推荐

