Django测试客户端POST命令没有通过301重定向注册

时间:2018-01-31 15:59:35

标签: django redirect heroku django-testing

我正在为现场Heroku服务器编写Django测试,并且无法让Django通过重定向识别POST请求。

在我的测试服务器上,一切正常:

views.py

def detect_post(request):
    """
    Detect whether this is a POST or a GET request.
    """

    if request.method == 'POST':

        return HttpResponse(
            json.dumps({"POST request": "POST request detected"}),
            content_type="application/json"
        )

    # If this is a GET request, return an error
    else:
        return HttpResponse(
            json.dumps({"Access denied": "You are not permitted to access this page."}),
            content_type="application/json"
        )

python manage.py shell

>>> from django.urls import reverse
>>> from django.test import Client
>>> c = Client()

# GET request returns an error, as expected:
>>> response = c.get(reverse('detectpost'), follow=True)
>>> response.status_code
200
>>> response.content
b'{"Access denied": "You are not permitted to access this page."}'

# POST request returns success, as expected
>>> response = c.post(reverse('detectpost'))
>>> response.status_code
200
>>> response.content
b'{"POST request": "POST request detected"}'

然而,当我搬到我的生产服务器时,我遇到了问题。我认为这是因为我的生产服务器有SECURE_SSL_REDIRECT,所以所有页面都重定向到同一页面的启用SSL的版本。以下是当我尝试在生产服务器上运行相同的测试代码时会发生什么:

heroku运行python manage.py shell

>>> from django.urls import reverse
>>> from django.test import Client
>>> c = Client()

# GET request returns an error, as expected:
>>> response = c.get(reverse('detectpost'), follow=True)
>>> response.status_code
200
>>> response.content
b'{"Access denied": "You are not permitted to access this page."}'

# POST request, however, has problems
>>> response = c.post(reverse('detectpost'), follow=True)
>>> response.status_code
200
>>> response.content
b'{"Access denied": "You are not permitted to access this page."}'
>>> response.redirect_chain
[('https://testserver/testpost/', 301)]

# I believe that the POST request isn't being detected because my site uses redirects
>>> response = c.post(reverse('detectpost'))
>>> response.status_code
301

如何通过重定向让我的Django TestClient注册POST请求?我期望follow=True标志能够实现这一点,但它似乎没有起作用。

1 个答案:

答案 0 :(得分:2)

使用client.post时,您可以通过设置https来模拟secure=True网址的请求。

response = c.post(reverse('detectpost'), follow=True, secure=True)

当Django安全中间件返回从httphttps的301重定向时,即使原始请求是POST请求,浏览器也会向新URL发出GET请求。

307 response告诉浏览器不要更改方法。但是我不会尝试让Django返回307.只需按照我的建议更改client.post()来电使用secure=True