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实现蓝桥杯模拟组织晚会

    问题描述 小明要组织一台晚会,总共准备了 n 个节目.然后晚会的时间有限,他只能最终选择其中的 m 个节目. 这 n 个节目是按照小明设想的顺序给定的,顺序不能改变. 小明发现,观众对于晚上的喜欢程度 ...

  2. Java实现 LeetCode 119 杨辉三角 II

    119. 杨辉三角 II 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例: 输入: 3 输出: [1,3,3,1] 进阶: ...

  3. java实现人民币金额大写

    在与财务相关的应用中,经常会用到人民币金额的大写,比如发票的打印程序. 本题的任务是:从键盘输入一个十亿以内的正整数(int类型),把它转换为人民币金额大写(不考虑用户输入错误的情况). 比如,用户输 ...

  4. 【CSS】常用色值

    常用颜色: 嫣红(red):#e54d42 桔橙(orange):#f37b1d 明黄(yellow):#fbbd08 橄榄(olive):#8dc63f 森绿(green):#39b54a 天青(c ...

  5. 记一次discuz修改首页图片路径问题

    1.找到图片路径拼装文件 首先打开根目录下的template目录找到首页文件 打开后找到图片列表的拼装位置 // 链接示例: <!--{eval $imagelistkey = getforum ...

  6. Java学习的一般过程

    伴随着科学技术的不断发展,世界开始走向信息化.网络化.大数据化.自然而然,计算机专业变得十分热门.尽管如此,计算机专业人才对社会来说仍然是供不应求,当然,这里指的是高层次技术人才.因此,对于我们这些占 ...

  7. python数据类型转换&&格式化输出

    ①python的数据类型包含:数字.字符串.列表.元组.字典.集合这六种基本数据类型.不同数据类型的数据可以进行类型的转换. 使用input让用户输入的数据默认为字符串类型: name = input ...

  8. win系统DOS批处理命令:每日根据定时计划,弹出相应的提醒

    @echo off setlocal enabledelayedexpansion ::设置数据源 ::set DATASET=D:\soft\xinyu\xinyu.txt ::获取系统时间的星期值 ...

  9. Flask Jinja2 知识点

    Jinja2模板引擎使用以下分隔符从HTML转义. {% ... %}用于语句 {{ ... }}用于表达式可以打印到模板输出 {# ... #}用于未包含在模板输出中的注释 # ... ##用于行语 ...

  10. Clear Writer v1.8 更新

    拖更了这么久之后,Clear Writer 诈尸啦(bushi 下载链接:https://linhongping.lanzous.com/ikF2Udmf7if Clear Writer v1.8 更 ...