Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render_to_string and response.content.decode() not matching

I'm writing my first Django app by following along with this book:

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

In the book there is a test that is verifying that the html is being returned as it is supposed to. Here is the test:

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)

My test is failing on the assertEqual test because I have added a csrf token in my HTML using the Django Template Language. Here is what my HTML page looks like:

<!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>

My assert is failing due to the render_to_string method not including the token. Here is what my two print statements included in my test print out:

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.

He doesn't have this problem in the book (he's using 1.8), so I was wondering if the method behavior has changed, or how I would write this test to pass.

like image 686
flybonzai Avatar asked Mar 10 '16 22:03

flybonzai


1 Answers

The request argument was added to render_to_string in Django 1.8. You could try changing the line in your test to:

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

It's only required to make this change in Django 1.9+, the test passes without the request in Django 1.8.

like image 173
Alasdair Avatar answered Nov 15 '22 06:11

Alasdair