2019-03-26 Tornado大纲

tornado

请求与响应

请求

  • 接收get传递参数

    • 获取请求URL中的参数: self.get_argument('name')/self.get_arguments('name')

    • self.get_query_argument('name')/ self.get_query_arguments('name')

  • 接收post传递参数

    • 获取请求体body传递的参数: self.get_argument('name')/self.get_arguments('name')

    • self.get_body_argument('name')/ self.get_body_arguments('name')

响应

Tornado应用

定义make_app函数

获取(返回)tornado.web.Application对象

  • 对象的参数handlers=[(访问路由,执行方法),]

  • 监听端口:Application对象.listen(端口)

执行方法类,需继承tornado.web.RequestHandler

  • 如果处理get请求,则定义def get(self)方法

  • 如果处理post请求,则定义def post(self)方法

启动

  • 获取应用: app = make_app()

  • tornado.ioloop.IOLoop.current().start()

命令行

定义默认的监听端口:

define('port', default=8080, type=int)

解析命令行中参数:parse_command_line()

获取命令行中的port参数:options.port

启动命令:python xxx.py --port=端口值

继承了RequestHandler的类

关于get等请求方法的应用

    def get(self, month, year, day):
        self.write('%s年%s月%s日' % (year, month, day))

    def post(self, month, year, day):
        self.write('post:只负责新增数据')
    
    def delete(self, month, year, day):
        self.write('delete:只负责删除')
    
    def patch(self, month, year, day):
        self.write('patch:修改部分属性')
    
    def put(self, month, year, day):
        self.write('put:修改全部属性')

### 跳转:self.redirect('/路由/')

### 一般在initialize方法中通过pymysql连接数据库

self.connect_obj = pymysql.connect(  host='127.0.0.1',  user='root',  password='zhuming',  database='flask9',  port=3306,  charset='utf8',  autocommit=True  )  # cursor参数pymysql.cursors.DictCursor定义取出的数据格式  self.cursor = self.connect_obj.cursor(pymysql.cursors.DictCursor)

### def initialize(self):

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n54" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">self.write('访问路由的时候开始时自动调用')</pre>

### def prepare(self):

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n56" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">self.write('访问路由的时候在initialize之后调用')</pre>

### 其他的get, post, put, patch, delete等方法写在中间

### def on_finish(self):

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n59" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">self.write('访问路由的时候结束时自动调用')</pre>

cookie

添加cookie:self.set_cookie('name', 'value', expires/expires_days)

  • 其中expires=日期,值可以通过datetime.now() + timedelta(days=值) 设置

  • 其中expires_days=正整数,代表几天后消失

删除cookie,只能删除值,不能删除键

self.clear_cookie('name') self.clear_all_cookies()

路由定义

第一种

  • 定义:tornado.web.Application(handlers=[(r'/days/(\d+)/(\d+)/', DaysHandler), ])

  • def get(self, month, day)

  • 注意:路由中的第一个参数,被函数中定义的month接收,第二个参数被函数中定义的day接收

第二种

  • 定义:tornado.web.Application(handlers=[(r'/days/(?P<name>\d+)/(?P<name2>\d2)', DaysHandler), ])

  • def get(self, name2, name)

  • 注意:路由中的第一个参数取名为name,第二个参数取名为name2

HTTP行为方法

GET:只用于获取数据

POST:只用于创建数据

PUT:修改某个对象的全部属性

PATCH:修改某个对象的部分属性

DELETE:删除数据

切入点函数

def initialize(self): 实例化初始内容,在调用行为方法之前将自动调用

def prepare(self): 在调用行为方法之前将自动调用

def on_finish(self): 在调用行为方法之后将自动调用

模板

模板文件路径定义:Application(handlers=[], template_path='指定templates文件夹的路径')

获取templates路径:os.path.join(os.path.dirname(os.path.abspath(file)), 'templates')

父模板

  • 挖坑:{% block name %} {% end %}

子模板

  • 继承:{% extends '父模板名称' %}

模板语法

  • 标签:{% 标签名 %} {% end %}

    • if标签:{% if 条件 %} {% end %}、{% if 条件 %} {% elif 条件 %} {% else %} {% end %}

    • for标签:{% for 变量 in [] %} {% end %}

    • set标签:{% set 变量=值 %}

    • while标签:{% while 条件 %} {% end %}

    • try标签:{% try %} {% except %} {% finally %} {% end %}

  • 变量:{{ 变量名 }}

  • 注解:{# 注解内容 #}

静态文件配置与使用

  • 配置:tornado.web.Application(handlers=[], template_path='', static_path='')

  • static_path=os.path.join(os.path.dirname(os.path.abspath(file)), 'static')

  • 导入静态文件: href='/static/css/xxx.css'、 href={{ static_url('css/xxx.css') }}

模型

1、模型定义:必须继承于Base = declarative_base(bind=engine)

2、数据库连接配置:mysql+pymysql://root:zhuming@127.0.0.1:3306/database

3、创建连接、引擎:create_engine(连接地址)

4、创建会话对象:

DbSession = session_maker(bind=engine) session = DbSession()

  • session.add(对象) session.commit()

  • session.add_all(对象列表) session,commit()

  • session.delete(对象) session.commit()

  • filter(条件).delete() session.commit()

  • session.query(模型).filter(条件).all() session.query(模型).filter(条件).first()

  • filter(模型名.字段 == 值)

  • filter_by(字段 = 值)

  • 同增的操作

  • filter(条件).update({'key': 'value', 'key2': 'value2'})

同步/异步

同步请求

class IndexHandler(tornado.web.RequestHandler):

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n169" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">def get(self):
 # 路由中传递的参数,/index/?q=python
 q = self.get_argument('q')
 # 向地址发送请求:https://cn.bing.com/search?q=
 client = tornado.httpclient.HTTPClient()
 response = client.fetch('https://cn.bing.com/search?q=%s' % q)
 print(response)
 self.write('同步测试')</pre>

异步请求

class IndexHandler(tornado.web.RequestHandler):

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n172" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">def get(self):
 # 路由中传递的参数,/index/?q=python
 q = self.get_argument('q')
 # 向地址发送请求:https://cn.bing.com/search?q=
 client = tornado.httpclient.HTTPClient()
 response = client.fetch('https://cn.bing.com/search?q=%s' % q)
 print(response)
 self.write('同步测试')</pre>

### 异步请求简化

class IndexHandler(tornado.web.RequestHandler):  @tornado.web.asynchronous  @tornado.web.gen.coroutine  def get(self):  q = self.get_argument('q')  client = tornado.httpclient.AsyncHTTPClient()  response = yield client.fetch('[https://cn.bing.com/search?q=%s](https://cn.bing.com/search?q=%25s)' % q)  print(response)  self.write('异步测试')

客户端与服务器保持连接

class ChatHandler(tornado.websocket.WebSocketHandler):  # 用于存放连接的对象  user_online = []

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n177" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">def open(self, *args, **kwargs):
 # 当进入chat.html页面时,会主动触发该函数
 self.user_online.append(self)
 for user in self.user_online:
 # 给每个在线用户推送这条消息
 # username = self.get_cookie('username')
 username = self.get_secure_cookie('username').decode('utf-8')
 user.write_message('系统提示:【%s】已进入聊天室' % username)
​
def on_message(self, message):
 # 接收前端传的数据
 username = self.get_secure_cookie('username').decode('utf-8')
 for user in self.user_online:
 # 给每个在线用户推送这条消息
 user.write_message('%s: %s' % (username, message))
​
def on_close(self):
 # 移除连接对象
 self.user_online.remove(self)
 for user in self.user_online:
 # 给每个在线用户推送这条消息
 username = self.get_secure_cookie('username').decode('utf-8')
 user.write_message('系统提示:【%s】已退出聊天室' % username)</pre>

后端方法

  • 业务类继承tornado.websocket.WebSocketHandler

  • def open(self, *args, **kwargs): 跳转到该路由时自动触发该函数

  • 向前端发送消息 self.write_message('内容')

  • def on_message(self, message):

    message就是前端传过来的数据

  • def on_close(self):

    移除连接对象的时候自动调用

前端方法

<!--建立连接-->  var websocket = new WebSocket('ws://127.0.0.1:80/chat/')

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" contenteditable="true" cid="n194" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> <!--获取后端返回的数据-->
 websocket.onmessage = function(e){
 console.log(e.data)
 $('#chat').append(e.data)
 $('#chat').append('<br>')
 }
​
 $('#btn').click(function(){
 <!--向后端发送数据-->
 var content = $('#content').val()
 websocket.send(content)
 })</pre>

*   在js中编写,首先建立一个连接  var websocket = new WebSocket('ws://127.0.0.1:80/路由名/')

*   获取后端返回的数据  websocket.onmessage = function(e){  console.log(e.data)  }

*   向后端发送数据  websocket.send(content)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容

  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    时光清浅03阅读 488评论 0 0
  • tornado框架是一款相较于其他web framework处理服务器性能问题更加强健的轻量级的强大的Pytho...
    恶人未满阅读 7,127评论 3 10
  • flask 环境 使用virtualenv创建 安装:pip install virtualenv 创建虚拟环境:...
    woming阅读 564评论 0 0
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,758评论 0 8
  • 醉梦红尘 A1: 醉难忘情深缠绵 寒梦现往事从前 延绵不绝涌心田 弦弄琴音妙曼 墨飞词赋翩跹 长笑红尘 踏浪扬帆 ...
    诗呆阅读 3,702评论 57 112