Django Import-Export导入报错:localtime()无法应用于naive datetime
问题解决:
localtime() cannot be applied to a naive datetime 导入报错 核心原因
报错源于Django时区机制与django-import-export的字段处理逻辑冲突:
- 你的
Reservation模型中,date_reserved字段默认值用了datetime.datetime.now(),生成的是无时区信息的naive datetime; - 当Django开启
USE_TZ=True(默认配置)时,django-import-export在生成导入差异对比时,会调用timezone.localtime()处理datetime字段,但该方法无法处理naive datetime,从而抛出错误。
可行解决方案
方案1:修改模型默认值为aware datetime
直接将模型中date_reserved的默认值替换为Django时区工具生成的aware datetime,从根源避免naive值:
# models.py from django.utils import timezone class Reservation(models.Model): reservation = models.OneToOneField(Vehicle, on_delete=models.CASCADE, primary_key=True,) delivered = models.BooleanField('Delivered',default=False) # 替换默认值为timezone.now date_reserved = models.DateTimeField('date reserved', default=timezone.now) ...
方案2:自定义Widget跳过本地时间转换
如果不想修改模型默认值,可自定义DateTimeWidget,重写render方法跳过timezone.localtime()调用:
# admin.py from import_export import resources, fields from import_export.widgets import DateTimeWidget from django.utils import timezone class NaiveDateTimeWidget(DateTimeWidget): def render(self, value, obj=None): if value is None: return "" # 直接格式化输出,不做本地时间转换 return value.strftime(self.format) class ReservationResource(resources.ModelResource): # 为date_reserved字段绑定自定义Widget date_reserved = fields.Field( column_name='date_reserved', attribute='date_reserved', widget=NaiveDateTimeWidget(format='%m/%d/%YT%H:%M:%S%z') # 匹配你的导入时间格式 ) class Meta: model = Reservation exclude = ('id',) import_id_fields = ('reservation',) fields = ( 'reservation', 'delivered', 'date_reserved', ... )
方案3:确保导入时间被解析为aware datetime
你的导入数据带时区信息(7/15/2022T00:00:00+00:00),可指定Widget的格式包含时区,让django-import-export正确解析为aware datetime:
# admin.py from import_export import resources, fields from import_export.widgets import DateTimeWidget class ReservationResource(resources.ModelResource): date_reserved = fields.Field( widget=DateTimeWidget(format='%m/%d/%YT%H:%M:%S%z') ) class Meta: model = Reservation exclude = ('id',) import_id_fields = ('reservation',) fields = ( 'reservation', 'delivered', 'date_reserved', ... )
为什么你之前的尝试无效
- 移除
SimpleHistoryAdmin:该组件与datetime字段的时区属性无关,无法解决核心问题; - 简化导入时间为
7/15/2022:解析后仍是naive datetime,依然触发localtime()报错; - 移除导入字段:模型默认值仍会生成naive datetime,导入时差异对比环节依然会处理该字段,导致报错。
内容的提问来源于stack exchange,提问作者JoeF
相关产品推荐
相关产品推荐

