Django-import-export admin导入带ForeignKey的CSV报KeyError:id
问题根因
触发KeyError: 'id'的核心问题出在DistrictResource的配置上:
exclude字段语法写错了。Python中单元素元组必须在元素末尾加逗号,你写的exclude = ('id')本质是个字符串,不是元组,django-import-export识别不到你要排除id字段,默认还是把id作为导入时的必填匹配主键,会去每一行导入数据里找id列,找不到就直接抛KeyError。- 自定义的
StateForeignKeyWiget完全多余,原生ForeignKeyWidget本身就支持指定关联表的匹配字段,重写get_queryset属于重复造轮子,反而容易引发匹配逻辑异常。
修正步骤
1. 替换resources.py代码
删掉冗余的自定义外键组件,修正exclude语法,最终代码如下:
from import_export import fields, resources from import_export.widgets import ForeignKeyWidget from damuwhatsapp.models import State, District class StateResource(resources.ModelResource): class Meta: model = State class DistrictResource(resources.ModelResource): state_name = fields.Field( column_name='state_name', attribute='state_name', widget=ForeignKeyWidget(State, field='state_name') ) district_name = fields.Field(column_name="district_name", attribute="district_name") class Meta: model = District # 注意单元素元组必须加尾部逗号,否则识别失败 exclude = ('id',) # 配置导入时用州名+区县名组合判断重复数据,避免重复导入 import_id_fields = ('state_name', 'district_name',) fields = ('state_name', 'district_name',)
2. 导入文件格式要求
上传的CSV/Excel文件必须带表头,第一列表头为state_name、第二列表头为district_name,且所有state_name的取值必须已经存在于State表中,否则会触发外键约束错误。
可选简化配置
如果不需要自定义字段属性,还可以把Resource写得更简洁,不用单独声明每个字段:
class DistrictResource(resources.ModelResource): class Meta: model = District exclude = ('id',) import_id_fields = ('state_name', 'district_name',) fields = ('state_name', 'district_name',) widgets = { 'state_name': ForeignKeyWidget(State, field='state_name') }
改完重启Django服务,再上传文件即可正常导入District数据,不会再出现id字段的KeyError。
内容的提问来源于stack exchange,提问作者Abhilash Singh Chauhan
相关产品推荐
相关产品推荐

