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

Django Test Client POST请求无法通过301重定向被识别的问题

解决Django Test Client在SSL重定向后无法识别POST请求的问题

这个问题核心是HTTP协议的默认行为导致的:当服务器返回301(永久重定向)或302(临时重定向)时,客户端会自动把POST请求转为GET请求继续访问重定向后的地址——哪怕你加了follow=True,Test Client也会严格遵循这个规则,所以重定向后你的请求就变成GET了,自然触发了视图里的拒绝逻辑。

下面给你几个可行的解决方案:

方案一:直接向HTTPS地址发送POST请求

既然生产环境强制HTTPS,那测试时直接用HTTPS的URL发起请求就行,这样就不会触发重定向了。你可以通过两种方式实现:

  • 构造完整的HTTPS URL:
response = c.post(f"https://testserver{reverse('detectpost')}")
  • 或者给Test Client设置secure=True,让所有请求默认使用HTTPS:
c = Client(secure=True)
response = c.post(reverse('detectpost'))

方案二:在测试环境临时禁用SSL重定向

如果你的测试不需要验证SSL重定向逻辑,只是想测试视图的POST处理能力,可以在测试运行时临时把SECURE_SSL_REDIRECT设为False。

你可以用override_settings装饰器在测试类里实现:

from django.test import override_settings, TestCase

class PostDetectionTest(TestCase):
    @override_settings(SECURE_SSL_REDIRECT=False)
    def test_post_request(self):
        c = Client()
        response = c.post(reverse('detectpost'))
        self.assertEqual(response.status_code, 200)
        self.assertIn(b'"POST request": "POST request detected"', response.content)

方案三:改用308重定向保留请求方法

HTTP 308(永久重定向)和307(临时重定向)是专门用来保留原始请求方法的重定向状态码。如果你的业务需要保留POST方法的重定向,可以修改Django的SSL重定向状态码:

在settings.py里添加配置:

SECURE_SSL_REDIRECT = True
# 把重定向状态码改成308,强制保留原始请求方法
SECURE_SSL_REDIRECT_STATUS_CODE = 308

这样当Test Client用follow=True发送POST请求时,重定向后的请求依然是POST,视图就能正确识别了。

不过要注意,这个设置会影响生产环境的所有SSL重定向,需要确认你的客户端都支持308状态码(大部分现代浏览器和HTTP客户端都已支持)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:33:26