tornado
請求與響應(yīng)
請求
-
接收get傳遞參數(shù)
獲取請求URL中的參數(shù): self.get_argument('name')/self.get_arguments('name')
self.get_query_argument('name')/ self.get_query_arguments('name')
-
接收post傳遞參數(shù)
獲取請求體body傳遞的參數(shù): self.get_argument('name')/self.get_arguments('name')
self.get_body_argument('name')/ self.get_body_arguments('name')
響應(yīng)
Tornado應(yīng)用
定義make_app函數(shù)
獲取(返回)tornado.web.Application對象
對象的參數(shù)handlers=[(訪問路由,執(zhí)行方法),]
監(jiān)聽端口:Application對象.listen(端口)
執(zhí)行方法類,需繼承tornado.web.RequestHandler
如果處理get請求,則定義def get(self)方法
如果處理post請求,則定義def post(self)方法
啟動
獲取應(yīng)用: app = make_app()
tornado.ioloop.IOLoop.current().start()
命令行
定義默認的監(jiān)聽端口:
define('port', default=8080, type=int)
解析命令行中參數(shù):parse_command_line()
獲取命令行中的port參數(shù):options.port
啟動命令:python xxx.py --port=端口值
繼承了RequestHandler的類
關(guān)于get等請求方法的應(yīng)用
def get(self, month, year, day):
self.write('%s年%s月%s日' % (year, month, day))
def post(self, month, year, day):
self.write('post:只負責(zé)新增數(shù)據(jù)')
def delete(self, month, year, day):
self.write('delete:只負責(zé)刪除')
def patch(self, month, year, day):
self.write('patch:修改部分屬性')
def put(self, month, year, day):
self.write('put:修改全部屬性')
### 跳轉(zhuǎn):self.redirect('/路由/')
### 一般在initialize方法中通過pymysql連接數(shù)據(jù)庫
self.connect_obj = pymysql.connect( host='127.0.0.1', user='root', password='zhuming', database='flask9', port=3306, charset='utf8', autocommit=True ) # cursor參數(shù)pymysql.cursors.DictCursor定義取出的數(shù)據(jù)格式 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('訪問路由的時候開始時自動調(diào)用')</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之后調(diào)用')</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('訪問路由的時候結(jié)束時自動調(diào)用')</pre>
cookie
添加cookie:self.set_cookie('name', 'value', expires/expires_days)
其中expires=日期,值可以通過datetime.now() + timedelta(days=值) 設(shè)置
其中expires_days=正整數(shù),代表幾天后消失
刪除cookie,只能刪除值,不能刪除鍵
self.clear_cookie('name') self.clear_all_cookies()
路由定義
第一種
定義:tornado.web.Application(handlers=[(r'/days/(\d+)/(\d+)/', DaysHandler), ])
def get(self, month, day)
注意:路由中的第一個參數(shù),被函數(shù)中定義的month接收,第二個參數(shù)被函數(shù)中定義的day接收
第二種
定義:tornado.web.Application(handlers=[(r'/days/(?P<name>\d+)/(?P<name2>\d2)', DaysHandler), ])
def get(self, name2, name)
注意:路由中的第一個參數(shù)取名為name,第二個參數(shù)取名為name2
HTTP行為方法
GET:只用于獲取數(shù)據(jù)
POST:只用于創(chuàng)建數(shù)據(jù)
PUT:修改某個對象的全部屬性
PATCH:修改某個對象的部分屬性
DELETE:刪除數(shù)據(jù)
切入點函數(shù)
def initialize(self): 實例化初始內(nèi)容,在調(diào)用行為方法之前將自動調(diào)用
def prepare(self): 在調(diào)用行為方法之前將自動調(diào)用
def on_finish(self): 在調(diào)用行為方法之后將自動調(diào)用
模板
模板文件路徑定義:Application(handlers=[], template_path='指定templates文件夾的路徑')
獲取templates路徑:os.path.join(os.path.dirname(os.path.abspath(file)), 'templates')
父模板
- 挖坑:{% block name %} {% end %}
子模板
- 繼承:{% extends '父模板名稱' %}
模板語法
-
標(biāo)簽:{% 標(biāo)簽名 %} {% end %}
if標(biāo)簽:{% if 條件 %} {% end %}、{% if 條件 %} {% elif 條件 %} {% else %} {% end %}
for標(biāo)簽:{% for 變量 in [] %} {% end %}
set標(biāo)簽:{% set 變量=值 %}
while標(biāo)簽:{% while 條件 %} {% end %}
try標(biāo)簽:{% try %} {% except %} {% finally %} {% end %}
變量:{{ 變量名 }}
注解:{# 注解內(nèi)容 #}
靜態(tài)文件配置與使用
配置:tornado.web.Application(handlers=[], template_path='', static_path='')
static_path=os.path.join(os.path.dirname(os.path.abspath(file)), 'static')
導(dǎo)入靜態(tài)文件: href='/static/css/xxx.css'、 href={{ static_url('css/xxx.css') }}
模型
1、模型定義:必須繼承于Base = declarative_base(bind=engine)
2、數(shù)據(jù)庫連接配置:mysql+pymysql://root:zhuming@127.0.0.1:3306/database
3、創(chuàng)建連接、引擎:create_engine(連接地址)
4、創(chuàng)建會話對象:
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):
# 路由中傳遞的參數(shù),/index/?q=python
q = self.get_argument('q')
# 向地址發(fā)送請求: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):
# 路由中傳遞的參數(shù),/index/?q=python
q = self.get_argument('q')
# 向地址發(fā)送請求: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('異步測試')
客戶端與服務(wù)器保持連接
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):
# 當(dāng)進入chat.html頁面時,會主動觸發(fā)該函數(shù)
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('系統(tǒng)提示:【%s】已進入聊天室' % username)
?
def on_message(self, message):
# 接收前端傳的數(shù)據(jù)
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('系統(tǒng)提示:【%s】已退出聊天室' % username)</pre>
后端方法
業(yè)務(wù)類繼承tornado.websocket.WebSocketHandler
def open(self, *args, **kwargs): 跳轉(zhuǎn)到該路由時自動觸發(fā)該函數(shù)
向前端發(fā)送消息 self.write_message('內(nèi)容')
-
def on_message(self, message):
message就是前端傳過來的數(shù)據(jù)
-
def on_close(self):
移除連接對象的時候自動調(diào)用
前端方法
<!--建立連接--> 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;"> <!--獲取后端返回的數(shù)據(jù)-->
websocket.onmessage = function(e){
console.log(e.data)
$('#chat').append(e.data)
$('#chat').append('<br>')
}
?
$('#btn').click(function(){
<!--向后端發(fā)送數(shù)據(jù)-->
var content = $('#content').val()
websocket.send(content)
})</pre>
* 在js中編寫,首先建立一個連接 var websocket = new WebSocket('ws://127.0.0.1:80/路由名/')
* 獲取后端返回的數(shù)據(jù) websocket.onmessage = function(e){ console.log(e.data) }
* 向后端發(fā)送數(shù)據(jù) websocket.send(content)