Django+Elasticsearch DSL报错:无法序列化datetime.time类型
问题描述
模型与数据结构
模型字段定义:
late_delivery = ObjectField()
对应的映射结构:
"late_delivery": { "City": { "delivery_time": TimeField, "order_time": TimeField, } }
示例数据:
"late_delivery": { "SomeCity": { "delivery_time": "23:00:00", "order_time": "22:00:00", }, }
需求与报错
要过滤出order_time小于当前时间的查询集,编写了如下过滤器代码:
class LateDeliveryFilter(BaseFilterBackend): def filter_queryset(self, request, queryset, view): late_delivery_requested = request.data.get("late_delivery", None) if not late_delivery_requested: return queryset now = datetime.now().time() queryset = queryset.filter(fulfillment=RB_STOCK) kwargs = { f"late_delivery__{settings.CITY_NAME}__order_time": {"lt": now} } return queryset.filter("range", **kwargs)
运行时报错:
TypeError("Unable to serialize datetime.time(12, 51, 22, 708584) (type: <class 'datetime.time'>)")
解决方法
这个错误是因为你直接使用datetime.time类型对象作为过滤条件,但你的ORM/数据库无法序列化该类型。需要将当前时间转换成与数据库存储格式一致的字符串形式。
具体修改点:
- 将
datetime.now().time()转为和示例数据匹配的"HH:MM:SS"格式字符串 - 调整过滤条件写法:ORM嵌套字段的比较需用
__lt后缀,而非字典形式,同时移除多余的"range"参数
修改后的代码:
from datetime import datetime class LateDeliveryFilter(BaseFilterBackend): def filter_queryset(self, request, queryset, view): late_delivery_requested = request.data.get("late_delivery", None) if not late_delivery_requested: return queryset # 转换为与存储格式一致的时间字符串 now_str = datetime.now().strftime("%H:%M:%S") queryset = queryset.filter(fulfillment=RB_STOCK) # 使用__lt操作符指定比较条件 queryset = queryset.filter( **{f"late_delivery__{settings.CITY_NAME}__order_time__lt": now_str} ) return queryset
额外注意:
- 如果数据库中存储的时间带毫秒,需改用
%H:%M:%S.%f格式生成字符串 - 确认ORM的嵌套字段过滤语法,比如适配MongoDB的Djongo框架,就是通过双下划线连接字段与操作符
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

