What is the Flask version of Django's render_to_string function?

Question:

So, I’m trying to learn TDD for Flask, by translating this code to Flask. I’ve been trying to find how to render a template to a string for a while now. Here is what I have tried:

render_template(...)
render_template_string(...)
make_response(render_template(...)).data

and none of them seem to work.

The error in each case seems to be

"...templating.py", line 126, in render_template
    ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'

in templating.py‘s render_template function.

My test code is as follows:

def test_home_page_can_save_POST_request(self):
    with lists.app.test_client() as c:
        c.get('/')
        rv = c.post('/', data = {'item_text':"A new list item"})

        # This test works
        self.assertIn("A new list item", rv.data)

    # This test doesn't
    self.assertEqual(rv.data,flask.make_response(flask.render_template('home.html',new_item_text='A new list item')).data)

with home.html as follows:

<html>
<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>{{ new_item_text }}</td></tr>
    </table>
</body>
</html>

Edit: I’ve added more files, because the error may be unrelated to the actual function used. I’m using exactly what Celeo has suggested in his answer.

Asked By: shashwat

||

Answers:

You’re on the right path with make_response:

response = make_response(render_template_string('<h2>{{ message }}</h2>', message='hello world'))

Then,

response.data

is

<h2>hello world</h2>

That response object is documented here.

Answered By: Celeo

Celeo is correct, but there are two additional things to consider (one of which is peculiar to the render_template function):

First, it looks like you have an indentation problem in your revised function. It looks like you’re calling rv.data outside of the “with” statement. The “assertEqual” statement should be within the same block/indentation-level as the “assertIn” statement. (It looks like you’ve placed it outside of the block at the moment.)

Second — and more importantly — the render_template function in flask adds newline characters at the beginning and end of the outputted HTML. (You can verify this from the python interactive shell by printing the following command to stdout:

flask.render_template('home.html',new_item_text='A new list item').data  # adds 'n' at start & end

The output you’ll get will have newline characters (“n”) at the beginning and end of the output.

Therefore, you should try stripping the output with the strip() function as shown below:

def test_home_page_can_save_POST_request(self):
    with lists.app.test_client() as c:
        c.get('/')
        rv = c.post('/', data = {'item_text':"A new list item"})

        self.assertIn("A new list item", rv.data)

        # Suggested Revision
        self.assertEqual(rv.data,flask.make_response(flask.render_template('home.html',new_item_text='A new list item')).data.strip())

That should hopefully do the trick.

Answered By: Malcriado415
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.