Django 的 render_to_string 函数的 Flask 版本是什么?
What is the Flask version of Django's render_to_string function?
所以,我正在尝试通过将 this 代码翻译成 Flask 来学习 Flask 的 TDD。一段时间以来,我一直在尝试寻找如何将模板呈现为字符串。这是我尝试过的:
render_template(...)
render_template_string(...)
make_response(render_template(...)).data
和 none 似乎有效。
每种情况下的错误似乎是
"...templating.py", line 126, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
在 templating.py
的 render_template
函数中。
我的测试代码如下:
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)
与home.html
如下:
<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>
编辑:我添加了更多文件,因为错误可能与实际使用的功能无关。我使用的正是 Celeo 在他的回答中建议的内容。
你在 make_response
的正确道路上:
response = make_response(render_template_string('<h2>{{ message }}</h2>', message='hello world'))
然后,
response.data
是
<h2>hello world</h2>
response
对象已记录 here。
Celeo 是正确的,但还有两件事需要考虑(其中一件是 render_template 函数特有的):
首先,您修改后的函数中似乎存在缩进问题。您似乎在 "with" 语句之外调用 rv.data 。 "assertEqual" 语句应与 "assertIn" 语句位于同一 block/indentation-level 中。 (看起来你现在把它放在了街区之外。)
其次——更重要的是——flask 中的 render_template 函数在输出的 HTML 的开头和结尾添加换行符。 (您可以通过将以下命令打印到标准输出来从 python 交互式 shell 验证这一点:
flask.render_template('home.html',new_item_text='A new list item').data # adds '\n' at start & end
您将获得的输出将在输出的开头和结尾处包含换行符 ("\n")。
因此,您应该尝试使用 strip() 函数剥离输出,如下所示:
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())
这应该可以解决问题。
所以,我正在尝试通过将 this 代码翻译成 Flask 来学习 Flask 的 TDD。一段时间以来,我一直在尝试寻找如何将模板呈现为字符串。这是我尝试过的:
render_template(...)
render_template_string(...)
make_response(render_template(...)).data
和 none 似乎有效。
每种情况下的错误似乎是
"...templating.py", line 126, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
在 templating.py
的 render_template
函数中。
我的测试代码如下:
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)
与home.html
如下:
<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>
编辑:我添加了更多文件,因为错误可能与实际使用的功能无关。我使用的正是 Celeo 在他的回答中建议的内容。
你在 make_response
的正确道路上:
response = make_response(render_template_string('<h2>{{ message }}</h2>', message='hello world'))
然后,
response.data
是
<h2>hello world</h2>
response
对象已记录 here。
Celeo 是正确的,但还有两件事需要考虑(其中一件是 render_template 函数特有的):
首先,您修改后的函数中似乎存在缩进问题。您似乎在 "with" 语句之外调用 rv.data 。 "assertEqual" 语句应与 "assertIn" 语句位于同一 block/indentation-level 中。 (看起来你现在把它放在了街区之外。)
其次——更重要的是——flask 中的 render_template 函数在输出的 HTML 的开头和结尾添加换行符。 (您可以通过将以下命令打印到标准输出来从 python 交互式 shell 验证这一点:
flask.render_template('home.html',new_item_text='A new list item').data # adds '\n' at start & end
您将获得的输出将在输出的开头和结尾处包含换行符 ("\n")。
因此,您应该尝试使用 strip() 函数剥离输出,如下所示:
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())
这应该可以解决问题。