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

Django TestCase调用self.client.post却发送GET请求触发405错误

Django测试中client.post实际发送GET请求导致405错误的解决方法

问题场景

编写Django集成测试时,self.client.get能正常发起请求,但调用self.client.post时,视图函数接收到的却是GET请求,最终返回HttpResponse("Method Not Allowed", 405),导致测试断言失败。

核心原因

Django测试客户端的post方法若传入完整绝对URL(如http://127.0.0.1:8201/v1/products/create),会触发内部重定向逻辑,自动将请求方法转为GET。测试客户端的设计初衷是优先使用相对路径模拟请求,绝对URL会被识别为外部跳转,从而改变请求方法。

解决步骤及代码修正

1. 将请求URL改为相对路径

去掉域名和端口,直接使用路由的相对路径,确保请求方法保持POST。

2. 正确传递请求数据(若为JSON格式)

如果视图期望接收JSON数据,需将字典序列化,并指定content_type,否则Django会默认按表单数据处理,可能导致解析失败。

3. 修正断言逻辑

response是HttpResponse对象,不能直接与字符串比较,需提取响应内容后再断言,同时建议先验证状态码。


修改后的测试代码

from django.test import TestCase
import json

class Test_Integration(TestCase):

    def test_create_exist_product(self):
        # 序列化JSON数据
        request_data = json.dumps({"name": "product7", "latest_version": "0"})
        # 使用相对路径发起POST请求
        response = self.client.post(
            '/v1/products/create',
            data=request_data,
            content_type='application/json',
            follow=True,
            secure=False
        )
        # 打印响应内容便于调试
        print(response.content.decode())
        # 先验证状态码,再断言响应文本
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.decode(), "Product name already exists")

对应视图函数的补充(若处理JSON数据)

import json
from django.http import HttpResponse
import logging

logger = logging.getLogger(__name__)

def create_product(request):
    logger.info("Entering function create_product..")
    logger.info("REQUEST TYPE: "+str(request.method))
    if request.method == "POST":
        # 解析JSON格式的请求体
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return HttpResponse("Invalid JSON data", status=400)
        
        name = data.get("name")
        latest_version = data.get("latest_version")
        
        # 业务逻辑:检查产品名称是否已存在
        if name == "product7":  # 示例判断逻辑,替换为实际业务代码
            return HttpResponse("Product name already exists")
        
        # 其他创建产品的逻辑...
        return HttpResponse("Product created successfully")
    
    # 非POST请求返回405
    return HttpResponse("Method Not Allowed", status=405)

验证效果

修改后重新运行测试,视图函数会正确接收到POST请求,执行对应的业务逻辑,返回预期的响应内容,测试断言即可通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:05:16