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
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 ...
随机推荐
- LOJ2557. 「CTSC2018」组合数问题
LOJ2557. 「CTSC2018」组合数问题 这道题是我第一道自己做完的题答题.考场上面我只拿了41分,完全没有经验.现在才发现其实掌握了大概的思路还是不难. 首先模拟退火,通过了1,2,6,9, ...
- Codeforces Round #429 (Div. 1) C. On the Bench(dp + 组合数)
题意 一个长度为 \(n\) 的序列 \(A\) ,定义一个 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,当且仅当 \(\forall i \in [1, n − 1], A_{p_i} ...
- Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)
题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...
- 【BZOJ5417】[NOI2018]你的名字(线段树,后缀自动机)
[BZOJ5417][NOI2018]你的名字(线段树,后缀自动机) 题面 BZOJ 洛谷 题解 首先考虑\(l=1,r=|S|\)的做法,对于每次询问的\(T\)串,暴力在\(S\)串的\(SAM\ ...
- Testlink解决大用例导入问题
最近公司同事需要将别的testlink的用例迁移过来,由于现在新的服务器也在使用,不能使用数据库导入的办法,只能用xml文件进行导入,不过在导入的时候出现了个没遇到的问题,报错文件太大,无法上传. 解 ...
- Libre OJ 130、131、132 (树状数组 单点修改、区间查询 -> 区间修改,单点查询 -> 区间修改,区间查询)
这三题均可以用树状数组.分块或线段树来做 #130. 树状数组 1 :单点修改,区间查询 题目链接:https://loj.ac/problem/130 题目描述 这是一道模板题. 给定数列 a[1] ...
- 洛谷P1173 [NOI2016]网格
这个码量绝对是业界大毒瘤...... 300行,6.5k,烦的要死...... 题意:给你一个网格图,里面有0或1.你需要把一些0换成1使得存在某两个0不四联通.输出最小的换的数量.无解-1. n,m ...
- @Async的简单用法总结
前言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时 候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3 ...
- axios 使用
<!DOCTYPE html> <html lang="en"> <head> {#导入静态文件#} {% load static %} < ...
- TCHAR和CHAR类型的互转,string 转lpcwstr
https://www.cnblogs.com/yuguangyuan/p/5955959.html 没有定义UNICODE,所以它里面的字符串就是简单用" "就行了,创建工程的时 ...