You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 23:27:28