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

如何测试Django同一视图中的两个表单 构造POST请求data对象

构造方法

Django表单设置prefix参数后,所有字段的提交键名会自动拼接{prefix}-{字段名}格式的前缀,后端也是按这个规则解析字段值,你之前的写法有两个明显错误:

  • {form_1_data, form_2_data}是Python集合语法,字典是可变类型不能放入集合,本身就会抛出类型错误,就算用解包语法合并字典,没给第二个表单字段加前缀也会导致表单校验失败。
  • 客户端POST提交的表单数据是单层键值对结构,不能嵌套传字典对象。

正确的构造逻辑是:给带prefix的表单所有字段名加上对应前缀,再和无prefix的表单字段合并为单层字典传入即可。

手动拼接示例

假设你给第二个表单设置的prefix值为author(替换成你代码里实际配置的prefix即可):

def test_post_success(self):
    # 无prefix的第一个表单字段,键名和单表单场景完全一致
    form_1_data = {
        "title": "Dombey and Son"
        # 其余第一个表单字段按原有规则写
    }
    # 带prefix的第二个表单字段,所有键名前加 "prefix-" 前缀
    form_2_data = {
        "author-name": "Charles Dickens",
        "author-country": "UK"
        # 键名规则严格为 {你配置的prefix值}-{原字段名}
    }
    # 合并两个字典为单层结构传入
    response = self.client.post(
        "/books/add/",
        data={**form_1_data, **form_2_data}
    )

    self.assertEqual(response.status_code, HTTPStatus.FOUND)
    self.assertEqual(response["Location"], "/books/")

免拼前缀的简便写法

如果怕手动拼前缀出错,可以直接实例化对应表单(实例化时传入和视图中完全一致的prefix参数),直接取表单的data属性拿到格式正确的字段字典,再合并即可:

from .forms import BookForm, AuthorForm

def test_post_success(self):
    # 实例化无prefix的表单
    book_form = BookForm(data={"title": "Dombey and Son"})
    # 实例化带prefix的表单,prefix参数必须和视图里的配置完全相同
    author_form = AuthorForm(
        data={"name": "Charles Dickens", "country": "UK"},
        prefix="author"
    )
    
    # 合并两个表单的合法数据直接提交
    response = self.client.post(
        "/books/add/",
        data={**book_form.data, **author_form.data}
    )

    self.assertEqual(response.status_code, HTTPStatus.FOUND)
    self.assertEqual(response["Location"], "/books/")

注意:Django测试客户端默认会帮你处理CSRF校验,一般不需要手动往data里加CSRF token字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:48:28