Django测试报错TypeError:__init__()收到意外关键字参数
问题直接原因
你遇到的TypeError核心原因是:ModelForm的初始化方法不支持直接将字段名作为关键字参数传入。DepartmentForm继承自ModelForm,它的__init__只接受框架定义的标准参数(比如data、instance、prefix等),而非你传入的department_name_text这类字段级别的关键字参数。
为什么DepartmentTestCase能正常运行?
看你的DepartmentTestCase代码,它调用的是self.get_department_form(department_name_text=self.department_name)——这个get_department_form方法应该是父类ModelTestCase中封装好的工具方法,内部逻辑会把你传入的关键字参数打包成字典,再作为data参数传给DepartmentForm。比如它可能的实现是:
def get_department_form(self, **kwargs): return DepartmentForm(data=kwargs)
而你在ProductTestCase里直接调用DepartmentForm(department_name_text=...),跳过了这个包装步骤,自然触发了参数错误。
修复方法
要正确初始化DepartmentForm,你需要把字段数据放到data参数中,或者直接把数据字典作为第一个位置参数传入:
错误写法(触发报错)
department = DepartmentForm(department_name_text=self.department_name)
正确写法二选一:
# 方式1:直接传数据字典作为第一个参数 department = DepartmentForm({'department_name_text': self.department_name}) # 方式2:显式指定data参数 department = DepartmentForm(data={'department_name_text': self.department_name})
为什么仅在外键场景下出现这个问题?
其实这个问题本质和外键无关——只是你在ProductTestCase里处理关联模型时,才开始手动初始化DepartmentForm,而DepartmentTestCase借助了父类的封装方法,所以没暴露问题。不过这里顺带提一个你ProductTestCase里的潜在优化点:
你给product_data的外键字段传的是模型实例('name_text': department_inst),如果这是给ProductForm的data参数用的,更规范的做法是传该实例的主键值(比如department_inst.pk),因为表单接收的是类似前端提交的原始数据(通常是主键ID);如果是要绑定现有实例到表单,那应该用instance参数而非data。
调整后的ProductTestCase示例
修正错误的表单初始化方式后,你的代码可以调整为:
class ProductTestCase(ModelTestCase): @classmethod def setUpTestData(cls): super(ProductTestCase, cls).setUpTestData() def setUp(self): super(ProductTestCase, self).setUp() # 正确初始化并验证Department表单 department_form = DepartmentForm({'department_name_text': self.department_name}) self.assertTrue(department_form.is_valid()) department_inst = department_form.save() # 用表单验证后保存更规范 # 同理处理Maker maker_form = MakerForm({'maker_name_text': self.maker_name}) self.assertTrue(maker_form.is_valid()) maker_inst = maker_form.save() self.product_data = { 'barcode_text': self.barcode, 'name_text': department_inst.pk, # 外键字段传主键ID 'from_maker': maker_inst.pk } def test_valid_input(self): product_form = ProductForm(self.product_data) self.assertTrue(product_form.is_valid())
内容的提问来源于stack exchange,提问作者user7120561

