小記初試tornado與ajax,一些注意點


一. 在 tornado模板中使用自定義方法

在tornado中可以使用兩種方式,達到在模板中調用自定義方法的效果,第一種是使用UIMethod 和UIModule

 

1.UIMethod使用方法示例如下:

(1)在項目中建立一個新py文件命名為uimethod:

需要注意的是,這里的函數都需要加一個參數self,否則會報錯

1 def show(self):
2     return "1111"
3 
4 def lower_case(self, arg):
5     return arg.lower()

原因是這里的函數,其實本質上是渲染模板的handler類的方法,如下圖中debug時候跟蹤的結果所示,self其實就是MainHandler的實例


(2)在程序入口文件中引入並注冊settings(key為ui_methods):

 1 import uimethods as mt
 2 
 3 # 其他的部分略...
 4 
 5 settings = {
 6     'template_path': 'template',
 7     'static_path': 'static',
 8     'static_url_prefix': '/static/',
 9     'ui_methods': mt,
10 }

 

(3)在模板中使用方法:

 

注意這里調用lower_case處的入參test,是必須在render模板的時候,傳入方法的,否則就是未定義,和其他直接在模板里使用的變量相同:

1 class MainHandler(tornado.web.RequestHandler):
2         @asynchronous
3         @gen.coroutine
4         def get(self):
5             is_authed = (self.get_cookie('auth', None) == USER)
6             self.render('index.html', is_authed=is_authed, user_id=self.get_cookie('auth', None), contents=CONTENTS, test='AA')

 

2. UIModule使用方法示例如下:

(1)創建文件

UIModule就是自定義類繼承UIModule,其方法render返回的內容在模板上調用類的時候會被顯示

1 from tornado.web import UIModule
2 from tornado import escape
3 
4 class showMod(UIModule):
5 
6     def render(self, *args, **kwargs):
7         return escape.xhtml_escape('333')

 

(2)在程序入口文件中引入並注冊settings(key為ui_mothods):

1 import uimethods as mt
2 
3 settings = {
4     'template_path': 'template',
5     'static_path': 'static',
6     'static_url_prefix': '/static/',
7     'ui_methods': mt,
8     'ui_modules': md,
9 }

 

(3)在模板中使用:

 

3. 然后小記一點tornado模板實現的原理:

實際上就是把模板的html,先根據{{與{%等特殊字符分割,將這些特殊部分外的字符串與特殊字符內的內容進行拼接;特殊字符內的字符串會經過一些特殊處理,比如獲取變量判斷類型,做python的邏輯判斷或者是循環或者是函數調用等等,然后這些運算結果與其他部分進行拼接。拼接的方式是生成如左圖這樣一個函數的字符串,該函數作用是將內容根據我之前說的步驟,append到_buffer的列表里。然后把這個字符串用compile和exec即可編譯執行。

對於函數中的參數如"title","data",是將render方法里面傳入的參數,作為namespace全局變量加入exec里面,這樣來實現的,簡單的模擬如下:

 

4. tornado當中還提供了一寫內置模板方法(其實也是用UIMothod,UIModule)實現的,小計如下:

  • escape: tornado.escape.xhtml_escape 的別名
  • xhtml_escape: tornado.escape.xhtml_escape 的別名
  • url_escape: tornado.escape.url_escape 的別名
  • json_encode: tornado.escape.json_encode 的別名
  • squeeze: tornado.escape.squeeze 的別名
  • linkify: tornado.escape.linkify 的別名
  • datetime: Python 的 datetime 模組
  • handler: 當前的 RequestHandler 對象
  • request: handler.request 的別名
  • current_user: handler.current_user 的別名
  • locale: handler.locale 的別名
  • _: handler.locale.translate 的別名
  • static_url: for handler.static_url 的別名
  • xsrf_form_html: handler.xsrf_form_html 的別名

 

 

二. static_path 和 static_url_prefix配置

 在tornado的settings當中,有兩個非必選參數 static_path和static_url_prefix,用來簡化關於靜態文件獲取的方法。使用實例如下:

 1. static_path 默認值為 static,也就是配置的所有靜態文件的根目錄,然后在模板或css中尋找文件路徑的時候,就不用都自己去做一寫絕對路徑的配置寫法了,方便統一管理修改,tornado就回到這里去找靜態文件。只需要在模板中使用方法static_url,就會自動生成訪問靜態文件的相對路徑,使用示例如下:

結果轉換出來的是:

可以看到自動在css前面加了static,后面的v=XXXXXXXX則是static_url的另外個功能即讓瀏覽器生成緩存記錄

 

 2.static_url_prefix 默認值為 /static/, 配置的是模板方法 static_url 里生成的結果里面 ,比如上面那個例子里面,就是/static/css前面的這個static,是可以改掉的,url就會不同。不過改這個不影響去找靜態文件的存儲路徑也就是static_path

 

 

三. tornado中對cookie的一些操作

 1. tornado中設置cookie示例:

1 self.set_cookie('auth', user_id, expires_days=30)

前兩個分別是cookie鍵和值,后面的expires_days是可選參數,設置過期時間。如果我們想操作用戶登出以后的cookie失效,可以改成expires_days=0。此外set_cookie還有個重要的可選參數是path,可以指定路徑,這個cookie就會只能在指定的路徑(路由頁面)生效。

 

2. 獲取cookie示例:

1 self.get_cookie('auth', None)

 

3. 給cookie加鹽示例:

tornado中的set_cookie和get_cookie是明文不加密傳輸的,set_secure_cookie和get_secure_cookie是明文加密傳輸的,使用后兩者的方法與前兩者相同,只是需要在settings里面多加一點,在tornado.web.Application中設置cookie_secret參數:

也就是為其加鹽!此外如果我們看一下set_secure_cookie的源碼,會發現其expires_days默認值為30,而set_cookie的默認值為None...也就是注意用了set_secure_cookie以后默認就會持續30天的,而且還發現set_secure_cookie當中並沒有path這個可選參數哦。

 

4. 此外RequestHandler 的cookies(示例用self.cookies)屬性是獲得所有cookie。

 

 

四. 對ajax發送的數據中含有中文的處理

在嘗試使用ajax向tornado后端發post請求時候,我發現發送的data里面帶有非拉丁字符的話,tornado在獲取是會產生錯誤,無法正確地用get_argument取到參數

這個時候可以使用js的“encodeURI”方法來進行編碼,示例如下:

1 var params = "article=" + encodeURI(text) + "&group=" + encodeURI(group);

這樣在py3的tornado中使用get_argument時候就能正確獲取了,而且也不用特意再decode。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM