Tornado的使用
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其非阻塞的方式和对 epoll 的运用
基本操作

tornado_base.py
# Author:song
import tornado.ioloop
import tornado.web #配置信息
settings = {
'static_path':'static',
'static_url_prefix':'/song/',#别名
'template_path':'templates',
}
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world") #返回数据 class LoginHandler(tornado.web.RequestHandler):
def get(self):
#self.get_argument('p') 获取请求参数,相当于django的request.GET.get('p')
#self.get_body_argument('name') 获取post内容信息
#self.set_cookie('k1','v1')设置cookie
#self.set_header('h1','v1')设置请求头
self.render("login.html",**{'k1':'song','k2':'shi','k3':[1,2,3,4],'k4':{'name':'a','age':18}}) #返回模板 def post(self, *args, **kwargs):
print(self.get_argument('user'))
self.redirect('https://home.cnblogs.com/u/master-song/')#重定向 #路由规则
application = tornado.web.Application([
(r"/index", MainHandler),
(r"/login", LoginHandler),
],**settings) if __name__ == "__main__":
#创建socket对象,将其加入select
application.listen(8888)
#开始循环监听
tornado.ioloop.IOLoop.instance().start()
模板login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/song/comment.css"/>
<title>Title</title>
</head>
<body>
<h1>login</h1>
{{k1}}
{{k2}}
<h1>列表</h1>
<ul>
{% for i in k3 %}
<li>{{i}}</li>
{% end %}
</ul>
<h1>字典</h1>
{{k4}}<br>
{{k4['name']}}<br>
{{k4.get('name')}}
<ul>
{% for k,v in k4.items() %}
<li>{{k}}:{{v}}</li>
{% end %}
<form method="post" action="login">
<input type="text" name="user"/>
<input type="submit" value="提交"/>
</ul>
</body>
</html>
login.html
comment.css 只写了一句
body{
background-color: blue;
}

login.html渲染图
Tornado默认提供的 UIMethod 和 UIModule,实现类似于Django的simple_tag的功能。
创建两个py文件

# Author:song def test1(self):
return '测试前端使用函数'
uimethods
# Author:song
from tornado.web import UIModule
from tornado import escape class test2(UIModule):
def embedded_css(self):
return 'body{color:blue}' #网页引入<style type="text/css">body{color:blue}</style>
def css_files(self):
return 'a.css'# 引入<link href="/song/a.css" type="text/css" rel="stylesheet">
def javascript_files(self):
return 'sk.js' #<script src="/song/sk.js" type="text/javascript"></script> def render(self, *args, **kwargs): print(args)#获取内容(123)
print(kwargs)#{}
# return escape.xhtml_escape('<h1>测试代码段前端渲染</h1>') #原样显示 <h1>测试代码段前端渲染</h1>
return '<h1>测试代码段前端渲染</h1>' #加载效果后显示
uimodules
在tornado_base.py中
import uimethods as mt
import uimodules as md
settings = {
'static_path':'static',
'static_url_prefix':'/song/',
'template_path':'templates',
'ui_methods':mt,
'ui_modules':md, #加上这两行
}

web组件的定制
1.session实现机制

# Author:song
import uuid #基于内存的写法
class Session(object):
container = {}
def __init__(self,handler):
# 获取用户cookie,如果有,不操作,否则,给用户生成随即字符串
# - 写给用户
# - 保存在session
nid = handler.get_cookie('session_id')
if nid:
if nid in Session.container:
pass
else:
nid = str(uuid.uuid4())
Session.container[nid] = {}
else:
nid = str(uuid.uuid4())
Session.container[nid] = {} handler.set_cookie('session_id', nid, max_age=1000)#设置cookie并设超时时间
# nid当前访问用户的随即字符串
self.nid = nid
# 封装了所有用户请求信息
self.handler = handler def __setitem__(self, key, value):
Session.container[self.nid][key] =value def __getitem__(self, item):
return Session.container[self.nid].get(item) def __delitem__(self, key):
del Session.container[self.nid][key] #基于redis
class RedisSession(object): def __init__(self,handler):
# 获取用户cookie,如果有,不操作,否则,给用户生成随即字符串
# - 写给用户
# - 保存在session
nid = handler.get_cookie('session_id')
if nid:
if nid in Session.container:
pass
else:
nid = str(uuid.uuid4())
# Session.container[nid] = {}
# 连接redis写值
# redis 服务器IP,端口(6379)
# 根据Nid是字符串 => 6871237123
# 6871237123 % 3 = 0,1,2
# ['10.1.11.2','10.1.11.3','10.1.11.4']
else:
nid = str(uuid.uuid4())
# Session.container[nid] = {}
# 连接redis写值 handler.set_cookie('session_id', nid, max_age=1000)
# nid当前访问用户的随即字符串
self.nid = nid
# 封装了所有用户请求信息
self.handler = handler def __setitem__(self, key, value):
#Session.container[self.nid][key] =value
pass
def __getitem__(self, item):
#return Session.container[self.nid].get(item)
pass def __delitem__(self, key):
# del Session.container[self.nid][key]
pass
session
# Author:song
# session_module = "RedisSession" # 只允许两种Session,RedisSession
session_module = "Session"
session_key
# Author:song
# Author:song
import tornado.ioloop
import tornado.web
from tornado_session import session_key #配置信息
settings = {
'static_path':'static',
'static_url_prefix':'/song/',
'template_path':'templates',
} class BaseHandler(object):
def initialize(self):
# 获取用户cookie,如果有,不操作,否则,给用户生成随即字符串
# - 写给用户
# - 保存在session
from tornado_session import session
session_module = getattr(session, session_key.session_module)#反向解析
self.session = session_module(self)
super(BaseHandler,self).initialize() class IndexHandler(BaseHandler, tornado.web.RequestHandler):
def get(self):
if self.session['is_login']:
self.write("Hello, world")
else:
self.redirect('/login') class LoginHandler(BaseHandler,tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render('login.html') def post(self, *args, **kwargs):
v = self.get_argument('user')
if v == 'song':
self.session['is_login'] = True
self.redirect('/index')
else:
self.redirect('/login') application = tornado.web.Application([
(r"/index",IndexHandler ),
(r"/login", LoginHandler),
],**settings)
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
tornado_session_test
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tornado-session</title>
</head>
<body>
<form method="post" action="login">
<input type="text" name="user"/>
<input type="submit" value="提交"/>
</form> </body>
</html>
login.html
如果选择使用redis,可能需要用到分布式
form简单表单验证

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tornado_form</title>
</head>
<body> <form method="post" action="login">
<!--<input type="text" name="user"/>-->
<!--<input type="email" name="email"/>-->
{% raw obj.user %}
{% raw obj.email %}
<input type="submit" value="提交"/>
</form> </body>
</html>
login.html
# Author:song
import tornado.web
import re
settings = {
'static_path': 'static',
'static_url_prefix': '/song/',
'template_path':'templates',
}
class StringField:
def __init__(self,name):
self.rex = "^\w+$"
self.name = name
self.value = ''
self.error = "" def __str__(self):
return "<input type='text' name='%s' value='%s' />" %(self.name,self.value,)
class EmailField:
def __init__(self,name):
self.rex = "^\w+@.*$"
self.name = name
self.value = ''
self.error = ""
def __str__(self):
return "<input type='text' name='%s' value='%s' />" %(self.name,self.value,) class LoginForm:
def __init__(self):
self.user = StringField(name='user')
self.email = EmailField(name='email') def is_valid(self,handler):
value_dict = {}
flag = True
for k,v in self.__dict__.items():
inp = handler.get_argument(k)
rex = re.match(v.rex,inp)
v.value = inp
if rex:
value_dict[k] = inp
else:
v.error = '%s 错误了..' %k
flag = False
return flag,value_dict class LoginHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs):
obj = LoginForm()
self.render('login.html',**{'obj': obj}) def post(self, *args, **kwargs):
obj = LoginForm()
valid,value_dict = obj.is_valid(self)
print(valid,value_dict)
if valid:
print(value_dict)
self.write('welcome')
else:
return self.render('login.html',**{'obj': obj}) application = tornado.web.Application([
(r"/login", LoginHandler),
],**settings) if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
tornado_form
Tornado的使用的更多相关文章
- Python(九)Tornado web 框架
一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过 ...
- 使用tornado,我们可以做什么?
以下介绍都是建立在python2.x的基础上面,tornado使用任意版本皆可. 如果我们需要对外提供一个http server(web api)/websocket server时,我们都可以使用t ...
- tornado session
[转]tornado入门 - session cookie 和session 的区别: 1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很安全,别人可以 ...
- tornado template
若果使用Tornado进行web开发可能会用到模板功能,页面继承,嵌套... 多页应用模板的处理多半依赖后端(SPA就可以动态加载局部视图),就算是RESTfull的API设计,也不妨碍同时提供部分模 ...
- tornado上手
http://www.tornadoweb.org/en/stable/ http://www.cnblogs.com/fanweibin/p/5418697.html import tornado. ...
- tornado+sqlalchemy+celery,数据库连接消耗在哪里
随着公司业务的发展,网站的日活数也逐渐增多,以前只需要考虑将所需要的功能实现就行了,当日活越来越大的时候,就需要考虑对服务器的资源使用消耗情况有一个清楚的认知. 最近老是发现数据库的连接数如果 ...
- centos 6.7 搭建tornado + nginx + supervisor的方法(已经实践)
首先,本来不想写这篇博客了,但是我测试了很多网上的例子包括简书的,全不行,我总结原因是自己太笨,搞了俩个晚上,后来决定,自己还是写一篇记录下来,保证自己以后使用 环境: centos6.7 64 py ...
- tornado中将cookie值设置为json字符串
不熟悉,找了很久,能FQ的话, https://groups.google.com/forum/#!topic/python-tornado/9Y--NgwjP_w 2楼有解释. tornado.es ...
- tornado 异步调用系统命令和非阻塞线程池
项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...
- 离线安装 Python 2.7, paramiko 和 tornado
无非就是离线安装, 步骤比较繁琐, 记录一下. 需求很简单, 一个离线安装的 Python, 能跑 tornado 和 paramiko 1. 离线安装 Python 2.7 .tgz cd Pyth ...
随机推荐
- Java实现 LeetCode 396 旋转函数
396. 旋转函数 给定一个长度为 n 的整数数组 A . 假设 Bk 是数组 A 顺时针旋转 k 个位置后的数组,我们定义 A 的"旋转函数" F 为: F(k) = 0 * B ...
- Java实现 LeetCode 120 三角形最小路径和
120. 三角形最小路径和 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
- Java中环境变量PATH与CLASSPATH的区别
在安装JDK时需要添加环境变量,经常使用的环境变量有两个: PATH与CLASSPATH 下面总结一下环境变量的作用. PATH是系统用来指定可执行文件的完整路径.当在CMD中执行命令时,如果执行的可 ...
- Android中如何使用多选对话框
final String [] ss={"A","B","C","D","E"}; boolean ...
- 【Python源码剖析】对象模型概述
Python 是一门 面向对象 语言,实现了一个完整的面向对象体系,简洁而优雅. 与其他面向对象编程语言相比, Python 有自己独特的一面. 这让很多开发人员在学习 Python 时,多少有些无所 ...
- Spring Boot 集成 Swagger 构建接口文档
在应用开发过程中经常需要对其他应用或者客户端提供 RESTful API 接口,尤其是在版本快速迭代的开发过程中,修改接口的同时还需要同步修改对应的接口文档,这使我们总是做着重复的工作,并且如果忘记修 ...
- ODEINT 求解常微分方程(2)
import numpy as np from scipy.integrate import odeint import matplotlib.pyplot as plt # function tha ...
- Vue —— VueX精讲(1)
大纲 这一讲我们最主要的就是学习vue中的数据管理VueX,这个是一个大杀器 一.回顾一些Promise相关的东西 Promise 有几个比较重要的方法,最重要的还是有一个叫做all的方法,这个也是非 ...
- DES/3DES/AES 三种对称加密算法实现
1. 简单介绍 3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称.它相当于是对每个数据块应用三次DES ...
- CISCN 2019-ikun
0x01 进去网址,页面如下: 刚开始有个登陆和注册的按钮,上图是我已经注册后登陆成功后的页面,我们发现在图的左下角给了一个关键的提示,购买LV6,通过寻找我们发现页面数很多,大概500页,一个一个找 ...