DRF返回ISO时间在Django模板格式化报错,求解决方案
解决DRF ISO时间格式在Django模板中转换显示的问题
问题背景
从DRF获取的JSON时间字段格式为:
'2023-04-15T16:22:03.721461+05:00'
需要在Django模板中显示为:
'15-04-2023 16:22'
但自定义模板标签运行时报错:
time data '2023-04-15T16:22:03.721461+05:00' does not match format "%Y-%m-%dT%H:%M:%S.%f+%Z'"
错误原因
- 格式字符串匹配错误:原代码用
%Z匹配时区,但%Z对应时区名称(如UTC、EST),无法匹配+05:00这种带符号的时区偏移量;且格式字符串末尾多了冗余的单引号。 - strptime局限性:
%z虽能匹配时区偏移,但仅支持±HHMM格式,不兼容带冒号的+05:00。 - 模板参数错误:原模板中
date:'d/m/Y H:M'里的M是月份缩写,分钟应该用i;目标格式是短横线分隔日期,需调整为d-m-Y。
修复方案
方案一:使用fromisoformat解析(推荐)
Python 3.7+提供的datetime.fromisoformat()可直接解析带冒号的时区偏移格式,无需手动构造格式字符串,简洁通用。
修改app/templatetags/event_extras.py:
import datetime from django import template register = template.Library() @register.filter(expects_localtime=True) def parse_iso(value): try: # 直接解析标准ISO 8601格式时间 return datetime.datetime.fromisoformat(value) except ValueError: # 解析失败时返回原值,避免页面报错 return value
方案二:兼容strptime的写法
若必须使用strptime,需先移除时区偏移中的冒号,让%z能匹配:
import datetime from django import template register = template.Library() @register.filter(expects_localtime=True) def parse_iso(value): try: # 移除时区偏移中的冒号,转换为%z支持的格式 value = value[:-3] + value[-2:] return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f%z") except ValueError: return value
正确模板使用方式
修正模板中的过滤器参数,确保日期格式和分钟符号正确:
{% load event_extras %} <th>{{ r.datetime|parse_iso|date:'d-m-Y H:i' }}</th>
内容的提问来源于stack exchange,提问作者m1rsadikov
相关产品推荐
相关产品推荐

