Tornado基本应用

Tornado简介

Tornado有自己的socket(异步非阻塞,原生支持WebSocket),Django没有。

Tornado的模板语言更接近Python风格,比Django要好理解。

Demo示例

from tornado import ioloop
from tornado.web import RequestHandler,Application

class IndexHandler(RequestHandler):
    def get(self):
        self.write("Hello, world")

application = Application([
    (r"/index", IndexHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    ioloop.IOLoop.instance().start()

  

Tornado路由系统以及通过别名反向生成url

from tornado import ioloop
from tornado.web import RequestHandler,Application

class IndexHandler(RequestHandler):
    def get(self):
        url1 = self.application.reverse_url(‘alias_name1‘)
        url2 = self.application.reverse_url(‘alias_name2‘,666)
        print(url1)
        print(url2)
        self.write("Hello, world")

class HomeHandler(RequestHandler):
    def get(self,uid):
        print(uid)
        self.write("Hello, Home")

application = Application([
    (r"/index", IndexHandler,{},‘alias_name1‘),
    (r"/home/(\d+)", HomeHandler,{},‘alias_name2‘),
])

# 支持通过域名进行匹配,域名匹配到然后再匹配 url
# application.add_handlers("blog.standby.pub",[
#     (r"/index", IndexHandler),
#     (r"/home/(\d+)", HomeHandler),
# ])

if __name__ == "__main__":
    application.listen(80)
    ioloop.IOLoop.instance().start()

  

种子管理系统

  路由系统

  多种方式实现登录验证

  cookie

  xsrf

  UImethod 和 UImodule

  模板引擎

  

目录结构

tree /f

│  app.py
│  my_uimethod.py
│  my_uimodule.py
│
├─controllers
│     account.py
│     seed.py
│     __init__.py
│
│
├─statics
│      commons.css
│      footer.css
│
├─tpl
       footer.html
       layout.html
       login.html
       seed.html
       video.html

  

app.py

from controllers.account import *
from controllers.seed import *
import my_uimethod
import my_uimodule

settings = {
    ‘template_path‘:‘tpl‘,
    ‘static_path‘:‘statics‘,
    ‘static_url_prefix‘:‘/static/‘,
    ‘xsrf_cookies‘: True, # csrf配置
    ‘cookie_secret‘:‘asahcaoclacnqwncakcnal‘,
    ‘login_url‘:‘/login.html‘,
    ‘ui_methods‘:my_uimethod,
    ‘ui_modules‘:my_uimodule,
}

application = Application([
    (r"/login.html", LoginHandler,{},‘login‘),
    (r"/logout.html", LogoutHandler,{},‘logout‘),
    (r"/seed.html", SeedHandler,{},‘seed‘),
    (r"/video.html", VideoHandler,{},‘video‘),
],**settings)

if __name__ == "__main__":
    application.listen(80)
    ioloop.IOLoop.instance().start()

  

account.py

from tornado import ioloop
from tornado.web import RequestHandler,Application

class LoginHandler(RequestHandler):
    def get(self,*args, **kwargs):
        self.render(‘login.html‘,msg="")

    def post(self, *args, **kwargs):
        """
        self.request 包含了所有数据:
            HTTPServerRequest(protocol=‘http‘,
            host=‘127.0.0.1‘,
            method=‘POST‘,
            uri=‘/login.html?next=%2Fseed.html‘,
            version=‘HTTP/1.1‘,
            remote_ip=‘127.0.0.1‘,
            headers={
              ‘Content-Type‘: ‘application/x-www-form-urlencoded‘,
              ‘Connection‘: ‘keep-alive‘,
              ‘Upgrade-Insecure-Requests‘: ‘1‘,
              ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36‘,
              ‘Cache-Control‘: ‘max-age=0‘,
              ‘Host‘: ‘127.0.0.1‘,
              ‘Accept-Encoding‘: ‘gzip, deflate, br‘,
              ‘Origin‘: ‘http://127.0.0.1‘,
              ‘Content-Length‘: ‘87‘,
              ‘Referer‘: ‘http://127.0.0.1/login.html?next=%2Fseed.html‘,
              ‘Accept-Language‘: ‘zh-CN,zh;q=0.9‘,
              ‘Accept‘: ‘text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8‘,
              ‘Cookie‘: ‘session=eyJ1c2VyX2luZm8iOiJhbGV4In0.DYUE4A.AhS8WvwJlQa8ium1YnF6tgJHwn0; _xsrf=2|50188c8e|5f181ad48a05219cb3bcf8117255223f|1520676667‘
            })
        """

        name = self.get_argument(‘name‘)    # 去GET和POST里取值
        pwd = self.get_argument(‘pwd‘)
        args = self.get_arguments(‘name‘)   # 类似Django里的 getlist()
        # self.get_query_argument()   # 去GET里取值
        # self.get_query_arguments()  # 类似Django里的 getlist()
        # self.get_body_argument()    # 去POST里取值
        # self.get_body_arguments()   # # 类似Django里的 getlist()

        if ‘alex‘ == name and ‘123‘ == pwd:
            import time
            deadline = time.time() + 3600
            # self.set_cookie(‘user_info‘,name,expires=deadline)  # 普通的cookie
            self.set_secure_cookie(‘user_info‘,name,expires=deadline) # 加盐/签名的cookie,需要在settings里配置cookie_secret

            # self.redirect(‘/seed.html‘)
            # url = self.reverse_url(‘seed‘)
            # self.redirect(url)

            # 如果使用authenticated来装饰login的get方法,并且在验证发现用户没有登录的情况下
            # 则在跳转到登录页面,并会自动带上一个next字段到get请求里:http://127.0.0.1/login.html?next=%2Fseed.html
            next_url = self.get_query_argument(‘next‘)
            if not next_url:
                next_url = self.reverse_url(‘seed‘)
            self.redirect(next_url)
        else:
            self.render(‘login.html‘,msg="用户名或密码错误")

class LogoutHandler(RequestHandler):
    def get(self,*args, **kwargs):
        self.write("Bye...")
    def post(self, *args, **kwargs):
        pass

  

seed.py

from tornado import ioloop
from tornado.web import RequestHandler,Application
from tornado.web import authenticated

# 手写实现登录验证
# class SeedHandler(RequestHandler):
#     def get(self,*args, **kwargs):
#         # name = self.get_cookie(‘user_info‘)
#         name = self.get_secure_cookie(‘user_info‘)
#         if not name:
#             self.redirect(‘/login.html‘)
#             return
#         self.write("Seed!")

""" 单继承
class ParentHandler(RequestHandler):
    # 这个方法是tornado给预留的,如果要使用 tornado.web.authenticated 来登录验证就必须自己重写这个方法
    def get_current_user(self):
        return self.get_secure_cookie(‘user_info‘)

# 使用装饰器实现登录验证
class SeedHandler(ParentHandler):

    @authenticated
    def get(self,*args, **kwargs):
        seed_list = [
            {‘title‘:‘小麦‘,‘price‘:20},
            {‘title‘:‘水稻‘,‘price‘:50},
            {‘title‘:‘玉米‘,‘price‘:30}
        ]
        self.render(‘seed.html‘,seed_list=seed_list)

class VideoHandler(ParentHandler):

    @authenticated
    def get(self, *args, **kwargs):
        video_list = [
            {‘title‘: ‘柯南‘, ‘price‘: 220},
            {‘title‘: ‘一人之下‘, ‘price‘: 90},
            {‘title‘: ‘虫师‘, ‘price‘: 40}
        ]
        self.render(‘video.html‘, video_list=video_list)

"""

""" 多继承 """
class ParentHandler(object):
    # 这个方法是tornado给预留的,如果要使用 tornado.web.authenticated 来登录验证就必须自己重写这个方法
    def get_current_user(self):
        return self.get_secure_cookie(‘user_info‘)

# 使用装饰器实现登录验证
class SeedHandler(ParentHandler,RequestHandler):

    @authenticated
    def get(self,*args, **kwargs):
        seed_list = [
            {‘title‘:‘小麦‘,‘price‘:20},
            {‘title‘:‘水稻‘,‘price‘:50},
            {‘title‘:‘玉米‘,‘price‘:30}
        ]
        self.render(‘seed.html‘,seed_list=seed_list)

class VideoHandler(ParentHandler,RequestHandler):

    @authenticated
    def get(self, *args, **kwargs):
        video_list = [
            {‘title‘: ‘柯南‘, ‘price‘: 220},
            {‘title‘: ‘一人之下‘, ‘price‘: 90},
            {‘title‘: ‘虫师‘, ‘price‘: 40}
        ]
        self.render(‘video.html‘, video_list=video_list)

  

自定义UIMethod以UIModule

def tab(self):
    """
    在html页面里的调用方式:
        {{ tab() }}
        {% raw tab() %}
    """
    # print(self)  # <controllers.seed.VideoHandler object at 0x000000000360D6A0>
    # return ‘UIMethod‘
    return "<a href=‘http://www.baidu.com‘>百度</a>"

def sum(self, num1, num2):
    return num1+num2

  

from tornado.web import UIModule
from tornado import escape

class Custom(UIModule):
    def render(self, *args, **kwargs):
        print(self,args,kwargs)
        return "UIModule 不仅可以返回内容还可以引入/嵌入 css和js,可以用来做一个自定制的组合模块,比如分页,只需要在使用的时候引入下就可以。"

    # 引入css
    def css_files(self):
        return ["/static/footer.css",]

    # 嵌入css
    def embedded_css(self):
        tpm = """
        .foot{
            height: 80px;
        }
        """
        return tpm

    # 引入js
    def javascript_files(self):
        return ["/static/common.js",]

    # 嵌入js
    def embedded_javascript(self):
        tpm ="""
        v = 123;
        console.log(v);
        """
        return tpm

  

seed.html

{% extends layout.html %}

{% block content %}

    <h1>种子列表</h1>

    {% module Custom(123) %}

    <ul>
        {% for item in seed_list %}
            <li> {{ item[‘title‘] }} - {{ item[‘price‘] }}</li>
            <li> {{ item.get(‘title‘,‘‘) }} - {{ item.get(‘price‘,‘‘) }}</li>
        {% end %}
    </ul>

     {% include ‘footer.html‘ %}
{% end %}

  

video.html

{% extends layout.html %}

{% block content %}

    <h1>视频列表 {{ sum(1,3) }}</h1>
    {{ tab() }}
    {% raw tab() %}
    <ul>
        {% for item in video_list %}
            <li> {{ item[‘title‘] }} - {{ item[‘price‘] }}</li>
            <li> {{ item.get(‘title‘,‘‘) }} - {{ item.get(‘price‘,‘‘) }}</li>
        {% end %}
    </ul>

{% end %}

  

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--<link rel="stylesheet" href="/static/commons.css">-->
    <link rel="stylesheet" href="{{ static_url(‘commons.css‘) }}">
</head>
<body>

<h1 class="c1">Login</h1>
<form action="" method="post">
    {% raw xsrf_form_html() %}
    <input type="text" name="name">
    <input type="text" name="pwd">
    <input type="submit" value="提交"> {{ msg }}
</form>

</body>
</html>

  

更多请参考:http://www.cnblogs.com/wupeiqi/articles/5702910.html

原文地址:https://www.cnblogs.com/standby/p/8541377.html

时间: 2024-10-10 06:33:06

Tornado基本应用的相关文章

微信小程序连接Tornado

自己搭建Tornado 监听8000端口, 提供给小程序访问的地址为http://127.0.0.1:8000/index #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): print('GET方式请求成功') self.write("123"

深入tornado中的IOStream

IOStream对tornado的高效起了很大的作用,他封装了socket的非阻塞IO的读写操作.大体上可以这么说,当连接建立后,服务端与客户端的请求响应都是基于IOStream的,也就是说:IOStream是用来处理连接的. 接下来说一下有关接收请求的大体流程: 当连接建立,服务器端会产生一个对应该连接的socket,同时将该socket封装至IOStream实例中(这代表着IOStream的初始化). 我们知道tornado是基于IO多路复用的(就拿epoll来说),此时将socket进行r

Tornado Web 框架

一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关有用工具及优化. Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以

Python框架之Tornado(二)请求阶段

概述 上图是tornado程序启动以及接收到客户端请求后的整个过程,对于整个过程可以分为两大部分: 启动程序阶段,又称为待请求阶段(上图1.2所有系列和3.0) 接收并处理客户端请求阶段(上图3系列) 简而言之: 1.在启动程序阶段,第一步,获取配置文件然后生成url映射(即:一个url对应一个XXRequestHandler,从而让XXRequestHandler来处理指定url发送的请求):第二步,创建服务器socket对象并添加到epoll中:第三步,创建无线循环去监听epoll. 2.在

tornado SSL3_READ_BYTES sslv3

////// ////// 支付宝回调,遇到问题 ////// WARNING:tornado.general:SSL Error on 9 ('110.75.248.125', 13675): [Errno 1] _ssl.c:504: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown ERROR:tornado.general:Uncaught exception Traceback (mo

tornado 资源

本章收集tornado(Python Web Framework)现有的资源 ##### introduction to tornado http://demo.pythoner.com/itt2zh/index.html document(tornadoweb) http://www.tornadoweb.org/en/stable/ http://www.tornadoweb.cn/documentation wiki(tornadoweb) https://github.com/torna

用 memcached 实现 Tornado 的 session 支持(一)

tornado 里面没有 session?不,当然有~我知道 github 上肯定有人帮我写好了~ O(∩_∩)O~ 于是乎,找到下面这个项目,用 memcached 实现 tornado 的 session.光会用可不行啊,让我们看看是怎么写的~ 项目地址:tornado-memcached-sessions 让我们先从 demo 看起.... app.py 中: 首先可以注意到,这里定义了一个新的 Application 类,继承于 tornado.web.Application, 在该类的

【从0开始Tornado建站】显示所有注册用户

显示注册用户的前台主要代码如下: {%block content%} <ul> {%for i in users%} <li><a href='/user/{{i[1]}}' class='text-success h4'>{{i[1]}}<small>({{i[3]}}星级)</small></a></li> {%end%} <br/> </ul> {%end%} 显示注册用户的后台代码如下: c

Tornado学习之异步原理

本文和大家分享的主要是Tornado 异步原理相关内容,一起来看看吧,希望对大家学习Tornado有所帮助. Tornado是什么? Tornado是一个用Python编写的异步HTTP服务器,同时也是一个web开发框架. Tornado 优秀的大并发处理能力得益于它的 web server 从底层开始就自己实现了一整套基于 epoll 的单线程异步架构. 同步.异步编程差异 .对于同步阻塞型Web服务器,我们来打个比方,将它比作一间饭馆,而Web请求就是来这家饭馆里吃饭的客人.假设饭馆店里只有

使用Tornado实现http代理

0x00 http代理 http代理的用处非常多,市面上也有公开的代理,可是有时候为了工作须要,比方分析应用层流量.做数据訪问控制.甚至做监控等等.Tornado提供了一些非常方便的环境和API,我们能够基于Tornado轻松实现一个http代理. 0x01 实现原理 http代理主要做client和web服务器之间的转发.这是大家都熟悉的场景,但仅仅限于http协议的情形.对于https的情况.这时候代理仅仅作为TCP中继进行信息中转,须要单独处理. 0x02 Tornado实现 基于Torn