Django import-export:自定义ForeignKeyWidget的clean方法未触发
问题分析与解决
核心原因:测试未使用自定义的LocalityResource
你在admin.py中定义了带有自定义PlaceForeignKeyWidget的LocalityResource,但测试代码里通过resources.modelresource_factory(model=Locality)()生成的是框架默认的资源类,完全没有调用你写的自定义资源,因此自定义Widget的clean方法根本不会被执行。
修复步骤
测试中导入并使用自定义资源类
修改test.py,直接导入你定义的LocalityResource,替换工厂方法生成的默认类:# test.py 修正部分 from crm.admin import LocalityResource # 导入自定义资源类 # 替换原初始化代码 locality_resource = LocalityResource()修正
import_id_fields的语法错误
当前代码里import_id_fields=("zip_id")实际是字符串类型,而非元组,会导致导入逻辑异常。需添加逗号确保是元组:# admin.py 中 LocalityResource 的 Meta 类 class Meta: model = Locality import_id_fields = ("zip_id",) # 加逗号明确为元组优化
clean方法逻辑(可选)
自定义Widget的clean方法里,row[r'place']无需转义,可简化为:val = Place.objects.create(name=row['place'])
完整修正后的测试代码示例
# test.py from crm.admin import LocalityResource from crm.models import Locality import tablib import pytest test_headers = [ "place", "zip_id", ] test_data = [ "NY", "2494", ] dataset = tablib.Dataset(test_data, headers=test_headers) @pytest.mark.django_db def test_locality_place_foreignkey(): # Act locality_resource = LocalityResource() # 使用自定义资源类 result = locality_resource.import_data(dataset, dry_run=False) assert Locality.objects.count() == 1 assert Place.objects.filter(name="NY").exists() # 验证自动创建的Place实例
额外说明
django-import-export的modelresource_factory是快速生成默认资源类的工具,当需要自定义字段、Widget或导入逻辑时,必须直接使用自己定义的ModelResource子类,否则所有自定义配置都会被框架忽略。
内容的提问来源于stack exchange,提问作者jjk
相关产品推荐
相关产品推荐

