知行编程网知行编程网  2023-01-08 12:30 知行编程网 隐藏边栏  30 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于十分钟学会web开发利器之tornado的相关知识,希望可以帮到处于编程学习途中的小伙伴


十分钟学会web开发工具tornado


一、从 hello, world 开始

如果你的 python 环境还没有安装 tornado,请直接使用 pip 安装:

pip install tornado

下面的代码,虽然只有六行(不包括导入模块的两行),却是一个完整的web服务程序。运行以下代码启动一个web服务,在本地浏览器直接访问http://127.0.0.1。如果不出意外的话,我们的第一个网页hello,world就可以正常显示了。


demo.py

# -*- coding: utf-8 -*-
import tornado.ioloop 
import tornado.web
class HomeHandler(tornado.web.RequestHandler): 
    def get(self): # 响应以get方式发送的请求
        self.write("hello, world") # 向请求者(浏览器)应答hello, world
app = tornado.web.Application([ (r"/", HomeHandler), ]) # URL映射
app.listen(80) # 绑定侦听端口
tornado.ioloop.IOLoop.instance().start() # 启动服务

如果你稍微了解一下http协议和get/post方法,相信你也能看懂。也许你的项目规划了很多url,也许你的服务需要监听80以外的端口,没关系,在这段代码上展开即可。仅仅六行! ! !请让我们向犀利、简洁、无所不能的python致敬!

要点:tornado.web.RequestHandler.write() 不仅可以接受字符串参数,还可以接受列表或字典参数——如果响应类型是json,这个重载特性是非常有效的。


二、最简单的登录

假定我们有这样一个 web 服务需求:

(1)首页:地址“/”,显示两个汉字“点击这里登录”,点击跳转到登录页面;

(2)登录页面:地址“/login”,通过get方法访问,会显示账号、密码输入框和登录按钮; post方式访问就是提交表单验证登录信息。登录成功则跳转到个人信息页面,否则跳转到首页;

(3)个人信息页:地址“/me”,显示登录账号。

基于以上代码,我们首先要做的是将URL与对应的处理类进行关联。这份工作其实很轻松愉快:

app = tornado.web.Application([
(r"/", HomeHandler), 
(r"/login", LoginHandler), 
(r"/me", MeHandler)
])

接下来,我们需要实现HomeHandler、LoginHandler和MeHandler这三个类。通常,我们习惯将这些URL对应的处理类保存为一个独立的文件,比如文件名为handlers.py,然后在服务端脚本demo.py中导入。


handlers.py

# -*- coding: utf-8 -*-
import tornado.web
class HomeHandler(tornado.web.RequestHandler): 
    """响应主页请求"""
    
    def get(self): # 以get方式请求
        self.write("""<!DOCTYPE html><html><body><a href="login">点此登录</a></body></html>""")
class LoginHandler(tornado.web.RequestHandler): 
    """响应登录页请求"""
    
    def get(self): # 以get方式请求
        self.write(
            """
            <!DOCTYPE html><html><body><form method="POST" action="/login">
                账号:<input type="text" name="account" value="" /><br />
                密码:<input type="password" name="passwd" value="" />
                <input type="submit" value="确定" />
            </form></body></html>
            """
        )
    
    def post(self): # 以post方式请求(本例为提交表单)
        account = self.get_argument('account', None)
        passwd = self.get_argument('passwd', None)
        
        if account == 'xufive' and passwd == 'dgdgwstd':
            self.redirect('/me?name=%s'%account)
        else:
            self.redirect('/')
class MeHandler(tornado.web.RequestHandler): 
    """响应个人信息页请求"""
    
    def get(self): # 以get方式请求
        name = self.get_argument('name', None)
        if name:
            self.write(
                """
                <!DOCTYPE html><html><head><meta charset="UTF-8" /></head>
                <body>欢迎你来到这里,%s</body></html>
                """%name
            )
        else:
            self.redirect('/')

相应地,服务脚本变成了这样:


demo.py

# -*- coding: utf-8 -*-
import os
import tornado.ioloop 
import tornado.web
from tornado.options import parse_command_line
from handlers import *
parse_command_line()
app = tornado.web.Application(
    handlers=[
        (r"/", HomeHandler), 
        (r"/login", LoginHandler), 
        (r"/me", MeHandler)
    ],
    template_path = os.path.join(os.path.dirname(__file__), 'templates')
)
app.listen(80) # 绑定侦听端口
tornado.ioloop.IOLoop.instance().start() # 启动服务

划重点:tornado.web.RequestHandler.get_argument() 可以读取通过表单和QueryString传递的参数。


三、模板技术

读到这里,你一定会疑惑:为什么服务器程序中会混入大量的html代码呢?别担心,上面的代码只是帮助你建立基本概念。事实上,Tornado 是为数不多的支持模板技术的框架之一。它的模板技术不仅支持继承,还支持子模板。让我们逐步讨论如何使用模板。

第1步:模板保存在哪儿?

在服务端脚本中,我们在使用tornado.web.Application()创建应用时,通常需要传递一个template_path参数,即模板文件的保存路径。上面的例子已经添加了这个参数,我们只需要将模板文件放在与demo.py同级的templates文件夹中即可。

第2步:怎样写模板?

模板其实就是一个html文件,只是里面夹杂着少量特别约定的符号而已。一个web项目通常由几个页面组成,这些页面有很多共同点,所以需要一个基类模板。


base.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <!-- 此处省略各种样式表文件 -->
  </head>
  <body>
  {% block block_body %}{% end %}
  </body>
<html>

基本模板 base.html 定义了一个 block_body 容器,如果需要,我们可以在基本模板的任何地方定义更多容器。假设我们需要一个个人信息页面模板,我们可以直接继承base.html,然后只填写block_body部分。


me.html

{% extends "base.html" %}
{% block block_body %}
<h1>欢迎你来到这里,{{name}}</h1>
{% end %}

在个人资料页面模板引用中,我们使用 {{}} 来引用变量名。

第3步:如何使用模板?

这很简单。之前我们使用 tornado.web.RequestHandler.write() 来响应浏览器。现在我们像这样使用模板:

class MeHandler(tornado.web.RequestHandler): 
    """响应个人信息页请求"""
    
    def get(self): # 以get方式请求
        name = self.get_argument('name', None)
        if name:
            self.render('me.html', name=name )
        else:
            self.redirect('/')

常用的模板语法汇总,如下:

(1)引用变量:{{…}}

(2)引用 python 表达式:{%…%}

(3)循环:{% for var in expr %}…{% end %}

(4)分支:{% if condition %}…{% elif condition %}…{% else %}…{% end %}

(5)引用原生表达式:{% raw expr %}


四、Cookie 演练

tornado.web.RequestHandler 的cookie 操作非常灵活。以下处理程序显示了读取和写入 cookie 的基本方法:

class CookieHandler(tornado.web.RequestHandler):
    def get(self):
        visit_num = self.get_cookie('visit_num')
        if not visit_num:
            visit_num = '0'
        visit_num = str(int(visit_num)+1)
        #self.set_cookie('visit_num', visit_num, expires=None) # 内存cookie
        self.set_cookie('visit_num', visit_num, expires=time.time()+1000) # 持久化的cookie
        self.write("这是你第%s次访问本页面"%visit_num)

如果我们要使用persistent cookies(硬盘cookies),为了防止被破解,一般都是加密的,那么需要在tornado.web.Application中设置cookie_secret项(加密因子)。

定义tornado.web.Application,这是我最常用的一个模式:

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", WelcomeHandler),                # 欢迎信息
            (r"/server_time",ServerTimeHandler)    # 显示服务器时间
        ]
        settings = dict(
            title = u"网站名称",
            template_path = os.path.join(os.path.dirname(__file__), 'templates'),
            static_path = os.path.join(os.path.dirname(__file__), 'static'),
            cookie_secret = 'rewqr4gfd654fdsg@$%34dfs',
            session_expiry = 0,
            login_url = "/",
            debug = 1
        )
        
        tornado.web.Application.__init__(self, handlers, **settings)


五、Session 扩展

给tornado添加session机制,基本思路是从tornado.web.RequestHandler派生一个新类,重写initialize()方法。当构造函数创建类实例时,将首先运行此方法。我们定义initialize()方法读取名为session_id的cookie,如果存在则读取以session_id命名的session文件获取session内容,否则session为空。

众多
,尽在python学习网,欢迎在线学习!

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享