【问题标题】:Render_to_string and response.content.decode() not matchingRender_to_string 和 response.content.decode() 不匹配
【发布时间】:2016-06-26 00:14:19
【问题描述】:

我正在编写我的第一个 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 测试中失败,因为我使用Django Template Language 在我的HTML 中添加了csrf token。这是我的 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),所以我想知道方法行为是否发生了变化,或者我将如何编写这个测试以通过。

【问题讨论】:

  • 测试驱动开发这本书最初是为 Django 1.7 编写的。看来这本书在升级到 Django 1.8 时可能遗漏了。
  • 作者在这里。它实际上对 1.8 是正确的,当您切换到 1.9 时会发生错误。书上的安装说明明明说要坚持1.8,咕咕咕……
  • @hwjp 我的错,测试在 Django 1.8 中确实通过了,安装说明明确说要坚持 1.8。当我认为我正在测试 1.8 时,我正在使用 Django 1.9。糟糕!
  • 嘿作者自己回复了!喜欢这本书,感谢您将其免费放到网上!我认为使用 1.9 会给我一个很好的机会来进行你在第一章中谈到的调试;)

标签: python django html


【解决方案1】:

我发现这个解决方案适用于最新的 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)
    )

【讨论】:

    【解决方案2】:

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

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

    只需在 Django 1.9+ 中进行此更改,在 Django 1.8 中无需请求即可通过测试。

    【讨论】:

    • request 参数是在 1.8 中添加的,但您只需要在 Django 1.9+ 中更新该行。在 Django 1.8 中,没有 request 的测试通过了。
    猜你喜欢
    • 2013-01-14
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 2011-12-21
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多