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

Django中允许为空的表单字段如何编写单元测试

问题解决方案

核心错误原因

你当前测试代码直接使用self.company.__dict__作为POST提交参数,混淆了模型层属性规则和表单提交数据规则:HTTP POST表单不存在None类型,空值对应空字符串,文件字段单独走文件流传输通道,所以直接传递模型实例属性会触发各类类型错误。


各场景处理方法

1. 数值型可空字段(如street_num)留空

POST提交时传空字符串''即可,Django的ModelForm会自动将合法的空输入转换为None存入数据库,不需要你手动给模型字段赋值''。

2. 字符型可空字段(如street_cplt)留空

POST提交时直接传空字符串''即可,符合表单校验规则。

3. 文件型可空字段(如logo)留空

POST参数中直接不携带该字段的键即可,如果需要传文件则放到client.post的files参数中,不要放在普通POST数据里。


修改后的测试代码示例

def create_dummy_company(name):
    return Company.objects.create(
        company_name=name,
        comp_slug=slugify(name),
        logo=SimpleUploadedFile(name='logo.jpg', content=b'content', content_type='image/jpeg'),
        street_num=1,
        street_cplt='测试补充地址',
        address='dummy address'
    )


class TestOptions(TestCase):

    def test_adm_options_update_nullable_fields(self):
        self.company = create_dummy_company("Test company")
        url = reverse("polls:adm_options", args=[self.company.comp_slug])
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        # 手动构造符合表单规则的POST参数,不要直接用模型的__dict__
        post_data = {
            "company_name": self.company.company_name,
            "comp_slug": self.company.comp_slug,
            "address": "new address",
            # 可空字段留空
            "street_num": "",
            "street_cplt": "",
            # logo字段直接不写,代表留空
        }
        response = self.client.post(url, post_data)
        self.company.refresh_from_db()
        self.assertEqual(response.status_code, 200)
        # 验证核心字段更新成功
        self.assertEqual(self.company.address, "new address")
        # 验证可空字段已正确设为空
        self.assertIsNone(self.company.street_num)
        self.assertEqual(self.company.street_cplt, "")
        self.assertFalse(self.company.logo)

额外优化建议

如果你需要测试保留原有logo不修改的场景,可以继续在POST参数中不携带logo字段,表单会默认保留实例原有值,不会清空。如果需要测试更新logo的场景,按如下方式提交即可:

post_data = {
    # 其他字段同上
}
files = {
    "logo": SimpleUploadedFile(name='new_logo.jpg', content=b'new_content', content_type='image/jpeg')
}
response = self.client.post(url, post_data, files=files)

内容的提问来源于stack exchange,提问作者Christophe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:27:00