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的使用的更多相关文章

  1. Python(九)Tornado web 框架

    一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过 ...

  2. 使用tornado,我们可以做什么?

    以下介绍都是建立在python2.x的基础上面,tornado使用任意版本皆可. 如果我们需要对外提供一个http server(web api)/websocket server时,我们都可以使用t ...

  3. tornado session

    [转]tornado入门 - session cookie 和session 的区别: 1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很安全,别人可以 ...

  4. tornado template

    若果使用Tornado进行web开发可能会用到模板功能,页面继承,嵌套... 多页应用模板的处理多半依赖后端(SPA就可以动态加载局部视图),就算是RESTfull的API设计,也不妨碍同时提供部分模 ...

  5. tornado上手

    http://www.tornadoweb.org/en/stable/ http://www.cnblogs.com/fanweibin/p/5418697.html import tornado. ...

  6. tornado+sqlalchemy+celery,数据库连接消耗在哪里

    随着公司业务的发展,网站的日活数也逐渐增多,以前只需要考虑将所需要的功能实现就行了,当日活越来越大的时候,就需要考虑对服务器的资源使用消耗情况有一个清楚的认知.     最近老是发现数据库的连接数如果 ...

  7. centos 6.7 搭建tornado + nginx + supervisor的方法(已经实践)

    首先,本来不想写这篇博客了,但是我测试了很多网上的例子包括简书的,全不行,我总结原因是自己太笨,搞了俩个晚上,后来决定,自己还是写一篇记录下来,保证自己以后使用 环境: centos6.7 64 py ...

  8. tornado中将cookie值设置为json字符串

    不熟悉,找了很久,能FQ的话, https://groups.google.com/forum/#!topic/python-tornado/9Y--NgwjP_w 2楼有解释. tornado.es ...

  9. tornado 异步调用系统命令和非阻塞线程池

    项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...

  10. 离线安装 Python 2.7, paramiko 和 tornado

    无非就是离线安装, 步骤比较繁琐, 记录一下. 需求很简单, 一个离线安装的 Python, 能跑 tornado 和 paramiko 1. 离线安装 Python 2.7 .tgz cd Pyth ...

随机推荐

  1. Java实现 LeetCode 224 基本计算器

    224. 基本计算器 实现一个基本的计算器来计算一个简单的字符串表达式的值. 字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 . 示例 1: 输入: "1 ...

  2. Java实现背包问题

    1 问题描述 给定n个重量为w1,w2,w3,-,wn,价值为v1,v2,-,vn的物品和一个承重为W的背包,求这些物品中最有价值的子集(PS:每一个物品要么选一次,要么不选),并且要能够装到背包. ...

  3. Java实现第八届蓝桥杯9算数式

    9算数式 题目描述 观察如下的算式: 9213 x 85674 = 789314562 左边的乘数和被乘数正好用到了1~9的所有数字,每个1次. 而乘积恰好也是用到了1~9的所有数字,并且每个1次. ...

  4. 用户管理命令-passwd

    passwd可以给用户设置密码或者修改密码,超级用户可以修改任何用户的密码,而且可以不遵守密码的复杂性原则,普通用户只能修改自己的密码,必须遵守密码的复杂性原则 passwd [选项] 用户名 常用选 ...

  5. gitee+picgo搭建个人博客图床

    gitee+picgo搭建个人博客图床 准备 首先需要去码云注册一个账号,并新建一个仓库.接着下载PicGO并安装好. 过程 点击左下方的插件设置. image 在搜索框中输入gitee搜索插件,安装 ...

  6. SimpleDateFormat 和 Calendar 对于时间的处理

    import java.text.SimpleDateFormat;import java.util.Date;public class test { public static void main( ...

  7. xlwings--Python for Excel

    xlwings 中文文档 xlwings,让excel飞起来! xlwings 的使用教程

  8. netty实现消息中心(二)基于netty搭建一个聊天室

    前言 上篇博文(netty实现消息中心(一)思路整理 )大概说了下netty websocket消息中心的设计思路,这篇文章主要说说简化版的netty聊天室代码实现,支持群聊和点对点聊天. 此demo ...

  9. activeMQ从入门到简单集群指南

    1.什么是amq MQ是消息中间件,基于JAVA的JMS消息服务机制来传递信息. 2.mq的作用 MQ给程序之间提供了一个缓冲,避免了在程序交互频繁的情况下,提高程序性能瓶颈和数据的可靠性 3.mq怎 ...

  10. FR嵌套报表(Nested Report)

    //主界面只是说明放置了哪些东西(3个ADOQuery不必放): //MasterSource.MasterField的设置如下: 1) Customer.Orders.Items 的 MasterS ...