Render_to_string和response.content.decode()不匹配

时间:2016-03-10 22:24:08

标签: python django html5

我按照本书编写了我的第一个Django应用程序:

http://chimera.labs.oreilly.com/books/1234000000754/ch05.html#_passing_python_variables_to_be_rendered_in_the_template

在书中有一个测试验证html是按照预期返回的。这是测试:

def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)
        expected_html = render_to_string('home.html')
        print(expected_html)
        print(response.content.decode())
        self.assertEqual(response.content.decode(), expected_html)

我的测试在assertEqual测试失败,因为我使用csrf token在我的HTML中添加了Django Template Language。这是我的HTML页面的样子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>To-Do lists</title>
</head>
<body>
    <h1>Your To-Do list</h1>
    <form method="POST">
            <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
            {% csrf_token %}
    </form>

    <table id="id_list_table">
        <tr><td>{{ new_item_list }}</td></tr>
    </table>
</body>
</html>

由于render_to_string方法不包含令牌,我的断言失败。以下是我的测试中包含的两个print语句:

F<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>To-Do lists</title>
</head>
<body>
    <h1>Your To-Do list</h1>
    <form method="POST">
            <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>

    </form>

    <table id="id_list_table">
        <tr><td></td></tr>
    </table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>To-Do lists</title>
</head>
<body>
    <h1>Your To-Do list</h1>
    <form method="POST">
            <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
            <input type='hidden' name='csrfmiddlewaretoken' value='VAiGvXZLHCjxWEWdjhgQRBwBSnMVoIWR' />
    </form>

    <table id="id_list_table">
        <tr><td></td></tr>
    </table>
</body>
</html>
F.

他在书中没有遇到这个问题(他使用1.8),所以我想知道方法行为是否已经改变,或者我是如何编写这个测试来通过的。

2 个答案:

答案 0 :(得分:6)

在Django 1.8中,request参数被添加到render_to_string。您可以尝试将测试中的行更改为:

expected_html = render_to_string('home.html', request=request)

它只需要在Django 1.9+中进行此更改,测试在Django 1.8中没有请求。

答案 1 :(得分:0)

我发现此解决方案适用于最新的Django版本-3.0.6

#add a function to the post request test function
def remove_csrf_tag(text):
    """Remove csrf tag from TEXT"""
    return re.sub(r'<[^>]*csrfmiddlewaretoken[^>]*>', '', text)

...
# then change assertion 
def test_home_page_can_save_a_POST_request(self):
...
 self.assertEqual(
        remove_csrf_tag(response.content),
        remove_csrf_tag(expected_html)
    )