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

Django-import-export admin导入带ForeignKey的CSV报KeyError:id

问题根因

触发KeyError: 'id'的核心问题出在DistrictResource的配置上:

  1. exclude字段语法写错了。Python中单元素元组必须在元素末尾加逗号,你写的exclude = ('id')本质是个字符串,不是元组,django-import-export识别不到你要排除id字段,默认还是把id作为导入时的必填匹配主键,会去每一行导入数据里找id列,找不到就直接抛KeyError。
  2. 自定义的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:06:57