django和tornado差別
* 性能
* 多線程或者多程序
* django使用的是( 多線程或者多程序)
* tornado使用的是協程(微線程),協程性能非常高(沒有線程這種上下文建立,切換的開銷)yield
* 功能
* django 大而全(什麼都有)(定制太困難了)
背景(admin)
orm(對象關系映射類庫)
session
* tornado 小而精 (輕量級)什麼也沒有
* tornado 單線程異步分阻塞(node.js)
* tornado适用場景
高并發,長連接配接
### tornado單線程異步分阻塞 ###
* 代碼
# 處理網絡請求的
class IndexHandler(tornado.web.RequestHandler):
# get請求
def get(self):
# 輸出響應體
self.write('hello world')
#Application 其實是一個設定的容器
app = tornado.web.Application([
(r'/',IndexHandler)
])
# 綁定端口(調用了HttpServer)
app.listen(8000)
# 死循環(從epoll中獲得需要操作的socket)
tornado.ioloop.IOLoop.instance().start()
* epoll
* 用戶端socket的儲存的容器
### 步驟 ###
* 清理類(RequestHandler)
* Application對象 (很多設定)
* app.listen(8000) 綁定端口,建立伺服器
* ioLoop.start(不斷的從epoll中讀取要處理的用戶端socket)
### 為什麼tornado能處理高并發,長連接配接 ###
* 長連接配接(epoll容器存儲起來了)
* 高并發(使用的是協程,沒有線程建立和線程上下文切換開銷)
def printa():
while True:
yield 'a'
def printb():
while True:
yield 'b'
while True:
pirnta()
printb()
abababababab
### tornado特性 ###
* 單線程
* 異步(協程)
* 非阻塞
### 查詢參數 ###
* get/post
* get get_query_argument get_query_arguments
* post get_body_argument get_body_arguments
* 縮寫 get_argument get_arguments(通用的)
* 捕獲
class TimeHandler(tornado.web.RequestHandler):
def get(self,year,month,day):
self.write('time'+year+month+day)
app = tornado.web.Application([
(r'/time/(?P<month>\d+)/(?P<year>\d+)/(?P<day>\d+)',TimeHandler),具名捕獲
(r'/time/(\d+)/(\d+)/(\d+)',TimeHandler),
])
* self.write(響應體)
* file,大檔案
### 查詢I(Input) ###
* get_argument 獲得get/post參數
* 捕獲/具名捕獲
* self.request.files 上傳多個檔案
* self.request.headers 請求頭
* self.request.remote_ip 獲得用戶端ip
class FileHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
if 'img' in self.request.files:
imgfile=self.request.files['img']
filename=imgfile[0]['filename']
filebody=imgfile[0]['body']
if not os.path.exists(MEDIA_ROOT):
os.makedirs(MEDIA_ROOT)
with open(os.path.join(MEDIA_ROOT,filename),'wb') as fw:
fw.write(filebody)
self.write('上傳成功')
class IPBlock(object):
def __init__(self,get_response):
self.get_response = get_response
def __call__(self, handler=None,*args, **kwargs):
BLACK_IP=['127.0.0.1']
if handler.request.remote_ip in BLACK_IP:
handler.write('禁止通路')
return
return self.get_response(handler)
class RemoteIPHandler(tornado.web.RequestHandler):
# @IPBlock
def get(self, *args, **kwargs):
self.write(u'您的ip是:'+self.request.remote_ip)
#get = IPBlock(get)
# IPBLOCK(get)(self,)
### 輸出O(Output) ###
* write () 響應體
* add_header()添加響應頭
self.add_header('name','張三')
* set_status 設定狀态碼
* 自定義重定向
class RedirctHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
# self.set_status(404,'照比到了')
self.set_status(302,'FOUND')
self.add_header('LOCATION','http://www.bjsxt.com')
* 重定向(302,301)self.redirct(位址)
* 301 永久重定向,
* set_cookie
class CookieHandle(tornado.web.RequestHandler):
def get(self,*args,**kwargs):
print(self.get_cookie('sessionid','找不到'))
import uuid
import datetime
self.set_cookie('sessionid',str(uuid.uuid4()),expires=datetime.datetime.utcnow()+ datetime.timedelta(minutes=30),path='/coo')
self.write('cookie')
* get_cookie
### 生命周期 ###
* initialize--》prepare-->get/post-->on_finish
* initialize和on_finish是一對,如果說initialize初始化工作,on_finish是清理功能。
* url中 (r'/',Handler,字典,name) #字典是給Handler中的initialize方法的
name的使用
class UserHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
print '使用者沒有登入到重定向login',self.reverse_url('lol')
self.redirect(self.reverse_url('lol'))
app = tornado.web.Application([
(r'/user',UserHandler),
URLSpec(r'/login',LoginHandler,name='lol'),
])
* write_error 出錯之後,會自動調用
* set_default_headers設定預設響應頭
* write_error和set_default_headers 一般寫在父類中,設定通用的響應頭
class DefaultHandler(tornado.web.RequestHandler):
def set_default_headers(self):
self.add_header('name','hello')
self.add_header('age',10)
def get(self, *args, **kwargs):
self.write('set_default_headers')
class CartHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
1/0 會出錯
self.write('測試錯誤')
def write_error(self, status_code, **kwargs):
print status_code,狀态碼
print kwargs出錯資訊
self.write('伺服器暫時維護中')
### url路由 ###
* 元組
* URLSpec
* 正則,處理類,初始化參數,名字(self.reverse_url('名字'))