Django-Import-Export添加delete字段后导入新设备报错求助
解决方案
问题出在默认的for_delete逻辑没有区分新建对象和已有对象:当导入新设备时,实例的id为None,但删除逻辑仍会被触发检查,导致报错。可以通过自定义for_delete方法解决,同时保留差异对比功能。
步骤1:修改Resource类的for_delete方法
在你的DeviceResource中,重写for_delete方法,仅对已存在的对象(即通过hostname匹配到的数据库记录)执行删除判断,新建对象直接跳过删除逻辑:
from import_export import resources, fields from import_export.widgets import BooleanWidget from .models import Device class DeviceResource(resources.ModelResource): # 定义delete字段 delete = fields.Field(widget=BooleanWidget(), column_name='delete') class Meta: model = Device fields = ('hostname', 'your_other_fields', 'delete') import_id_fields = ('hostname',) # 用hostname作为唯一匹配标识 def for_delete(self, row, instance): # 仅当实例已存在(pk不为None)且delete字段为True时,返回允许删除 return instance.pk is not None and self.fields['delete'].clean(row)
原理说明
import_id_fields = ('hostname',):导入时会根据hostname查找数据库中已有的设备,找到则返回对应实例(有pk),找不到则创建新实例(pk为None)。- 重写的
for_delete方法:只有当实例是已存在的数据库记录(pk不为None),且CSV中delete字段为1(或True)时,才触发删除操作。新建对象直接返回False,不会进入删除校验逻辑,也就避免了id attribute is set to None的错误。
验证效果
- 导入已有设备且
delete=1:正常删除对应设备; - 导入新设备(
hostname未在数据库中)且delete=0:正常创建新设备,无报错; - 差异对比功能保留:新建/修改的设备差异会正常显示,无需设置
skip_diff=True。
内容的提问来源于stack exchange,提问作者ferran
相关产品推荐
相关产品推荐

