Django-Import-Export导入报错:AttributeError: 'str'对象无'year'属性
嘿,我来帮你排查这个导入报错的问题!你遇到的AttributeError: 'str' object has no attribute 'year',核心原因很明确:你把Django DateField需要的date对象转成了字符串,导致后续处理时框架试图调用字符串的year属性,自然就报错了。
问题出在哪?
看你在before_save_instance里写的代码:
instance.edit_date = parse(instance.edit_date).strftime('%y/%m/%d')
parse()本来已经把CSV里的日期字符串转成了合法的datetime对象,但你紧接着用strftime又把它转回了字符串格式——而Django的DateField字段只接受Python的date/datetime对象,不接受字符串,这就踩坑了。
怎么修复?
我给你两个靠谱的解决方案,选哪个都行:
方案1:修正before_save_instance,保留date对象
把字符串转换的步骤删掉,直接保留解析后的date对象,同时要处理空值(比如你的premiere_date允许为空):
from datetime import datetime from dateutil.parser import parse def before_save_instance(self, instance, using_transactions, dry_run): # 处理edit_date:如果是字符串,转成date对象 if instance.edit_date and isinstance(instance.edit_date, str): instance.edit_date = parse(instance.edit_date).date() # 处理premiere_date:空值就跳过,非空则转成date对象 if instance.premiere_date and isinstance(instance.premiere_date, str): instance.premiere_date = parse(instance.premiere_date).date() return instance
方案2:用import-export的DateWidget更省心
其实import-export框架本身就有处理日期解析的DateWidget,直接在Resource类里给日期字段指定格式就行,不用自己写before_save_instance,更符合框架设计:
from import_export import resources, fields from import_export.widgets import DateWidget from .models import YourModel # 替换成你的实际模型类 class YourModelResource(resources.ModelResource): # 给每个日期字段指定CSV里的日期格式(比如你的CSV是7/6/20,对应%m/%d/%y) edit_date = fields.Field( column_name='edit_date', attribute='edit_date', widget=DateWidget(format='%m/%d/%y') ) premiere_date = fields.Field( column_name='premiere_date', attribute='premiere_date', widget=DateWidget(format='%m/%d/%y') ) class Meta: model = YourModel # 只列出需要导入的字段,那些不需要的DateTimeField(created/updated等)可以不用加 fields = ('edit_date', 'premiere_date', '你的其他字段...')
额外优化:处理DateTimeField的空值
你的created、updated这些DateTimeField如果CSV里没有数据,完全不用在CSV里加空表头——直接在模型里设置自动值更方便:
# models.py里修改这几个字段 created = models.DateTimeField(blank=True, auto_now_add=True) # 创建时自动设为当前时间 updated = models.DateTimeField(blank=True, auto_now=True) # 每次保存自动更新为当前时间 deleted_at = models.DateTimeField(blank=True, null=True)
这样Django会自动处理这些字段的值,根本不用你在导入时操心。
最后验证
修改完之后,重新导入CSV时注意:
- 确保CSV里的日期格式和你设置的
DateWidget格式完全匹配 - 空的
premiere_date字段不会引发报错 - 那些DateTimeField的自动值正常生效
内容的提问来源于stack exchange,提问作者stevec
相关产品推荐
相关产品推荐

