返回介绍

2.1 简单示例:Poem Maker Pro

发布于 2025-03-08 19:24:49 字数 5471 浏览 0 评论 0 收藏 0

让我们以一个叫作 Poem Maker Pro 的简单例子开始。Poem Maker Pro 这个 Web 应用有一个让用户填写的 HTML 表单,然后处理表单的结果。代码清单 2-1 是它的 Python 代码。

代码清单 2-1 简单表单和模板:poemmaker.py

import os.path

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

class PoemPageHandler(tornado.web.RequestHandler):
    def post(self):
        noun1 = self.get_argument('noun1')
        noun2 = self.get_argument('noun2')
        verb = self.get_argument('verb')
        noun3 = self.get_argument('noun3')
        self.render('poem.html', roads=noun1, wood=noun2, made=verb,
                difference=noun3)

if __name__ == '__main__':
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers=[(r'/', IndexHandler), (r'/poem', PoemPageHandler)],
        template_path=os.path.join(os.path.dirname(__file__), "templates")
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

除了 poemmaker.py,你还需要将代码清单 2-2 和代码清单 2-3 中的两个文件加入到 templates 子文件夹中。

代码清单 2-2 Poem Maker 表单:index.html

<!DOCTYPE html>
<html>
    <head><title>Poem Maker Pro</title></head>
    <body>
        <h1>Enter terms below.</h1>
        <form method="post" action="/poem">
        <p>Plural noun<br><input type="text" name="noun1"></p>
        <p>Singular noun<br><input type="text" name="noun2"></p>
        <p>Verb (past tense)<br><input type="text" name="verb"></p>
        <p>Noun<br><input type="text" name="noun3"></p>
        <input type="submit">
        </form>
    </body>
</html>

代码清单 2-3 Poem Maker 模板:poem.html

<!DOCTYPE html>
<html>
    <head><title>Poem Maker Pro</title></head>
    <body>
        <h1>Your poem</h1>
        <p>Two {{roads}} diverged in a {{wood}}, and I—<br>
I took the one less travelled by,<br>
And that has {{made}} all the {{difference}}.</p>
    </body>
</html>

在命令行执行下述命令:

$ python poemmaker.py --port=8000

现在,在浏览器中打开 http://localhost:8000 。当浏览器请求根目录(/)时,Tornado 程序将渲染 index.html,展示如图 2-1 所示的简单 HTML 表单。

图 2-1

图 2-1 Poem Maker Pro:输入表单

这个表单包括多个文本域(命名为 noun1、noun2 等),其中的内容将在用户点击"Submit"按钮时以 POST 请求的方式送到 /poem 。现在往里面填写东西然后点击提交吧。

为了响应这个 POST 请求,Tornado 应用跳转到 poem.html,插入你在表单中填写的值。结果是 Robert Frost 的诗《The Road Not Taken》的轻微修改版本。图 2-2 展示了这个结果。

图 2-2

图 2-2 Poem Maker Pro:输出

2.1.1 渲染模板

从结构上讲,poemmaker.py 和 第一章 中的例子很相似。我们定义了几个 RequestHandler 子类并把它们传给 tornado.web.Application 对象。那么有什么不一样的地方呢?首先,我们向 Application 对象的 init 方法传递了一个 template_path 参数。

template_path=os.path.join(os.path.dirname(__file__), "templates")

template_path 参数告诉 Tornado 在哪里寻找模板文件。我们将在本章和 第三章 中讲解其确切性质和语法,而它的基本要点是:模板是一个允许你嵌入 Python 代码片段的 HTML 文件。上面的代码告诉 Python 在你 Tornado 应用文件同目录下的 templates 文件夹中寻找模板文件。

一旦我们告诉 Tornado 在哪里找到模板,我们可以使用 RequestHandler 类的 render 方法来告诉 Tornado 读入模板文件,插入其中的模版代码,并返回结果给浏览器。比如,在 IndexHandler 中,我们发现了下面的语句:

self.render('index.html')

这段代码告诉 Tornado 在 templates 文件夹下找到一个名为 index.html 的文件,读取其中的内容,并且发送给浏览器。

2.1.2 填充

实际上 index.html 完全不能称之为"模板",它所包含的完全是已编写好的 HTML 标记。这可以是模板的一个不错的使用方式,但在更通常的情况下我们希望 HTML 输出可以结合我们的程序传入给模板的值。模板 poem.html 使用 PoemPageHandler 渲染,是这种方式的一个很好的例子。让我们看看它是如何工作的吧。

在 poem.html 中,你可以看到模板中有一些被双大括号({{和}})括起来的字符串,就像这样:

<p>Two {{roads}} diverged in a {{wood}}, and I—<br/>
I took the one less travelled by,<br>
And that has {{made}} all the {{difference}}.</p>

在双大括号中的单词是占位符,当我们渲染模板时希望以实际值代替。我们可以使用向 render 函数中传递关键字参数的方法指定什么值将被填充到 HTML 文件中的对应位置,其中关键字对应模板文件中占位符的名字。下面是在 PoemPageHandler 中相应的代码部分:

noun1 = self.get_argument('noun1')
noun2 = self.get_argument('noun2')
verb = self.get_argument('verb')
noun3 = self.get_argument('noun3')
self.render('poem.html', roads=noun1, wood=noun2, made=verb, difference=noun3)

在这里,我们告诉模板使用变量 noun1(该变量是从 get_argument 方法取得的)作为模板中 roads 的值,noun2 作为模板中 wood 的值,依此类推。假设用户在表单中按顺序键入了 pineapples、grandfather clock、irradiated 和 supernovae,那么结果 HTML 将会如下所示:

<p>Two pineapples diverged in a grandfather clock, and I—<br>
I took the one less travelled by,<br>
And that has irradiated all the supernovae.</p>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文