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 389 找不同
389. 找不同 给定两个字符串 s 和 t,它们只包含小写字母. 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. 请找出在 t 中被添加的字母. 示例: 输入: s = " ...
- Java实现 LeetCode 217 存在重复元素
217. 存在重复元素 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3 ...
- UVIYN MMDVM充电宝支持APRS与 YSF
需求就是要在APRS地图上显示对讲机位置 1.打开pi-star首页链接配置的专家(EXPERT)设置 下面链接快速打开 http://ip/admin/expert/edit_ysfgateway. ...
- windows server2012在已有.net4.5框架的基础上安装.net3.5的方法
我们在一台服务器运行各种程序的时候难免会用到一些好用的但是很老的软件.老软件也就难免需要以前的那种环境来运行,但是老的环境与新的环境往往不兼容.下面我就来讲一讲系统在已有.net4.5的情况下怎么安装 ...
- bootargs说明 和 下位机静态ip的设置
setenv bootargs root=/dev/nfs nfsroot=192.168.1.8:/opt/rootfs ip=192.168.1.110:192.168.1. ...
- MATLAB作图之一
问题 在使用MATLAB当中的imagesc作图的时候,如果数据矩阵元素太少,得到的图看起来会很"粗糙"(图1).那么如何得到更为"圆润"的图像呢? A = r ...
- java处理csv文件上传示例
前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理. ReadCsvUtil工具类 package com.hanfengyeqiao.g ...
- 列表、元组、字典和简单if语句【python实验1】
第一次实验报告: 学生姓名 总成绩 tom 90 jack 89 john 96 kate 86 peter 100 实验内容3-1 建立两个列表分别对学生的姓名和总成绩信息进行存储 name=['t ...
- vscode 常用变量
${workspaceFolder} the path of the workspace folder that contains the tasks.json file ${workspaceRoo ...
- vs2017离线包下载获取方法
一.去官网下载所需要的版本的安装包获取程序: https://www.visualstudio.com/zh-hans/downloads/ 三个版本,对应文件名称为: 社区版:vs_Communit ...