<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 模板 已經基本了解前端向和后端如何傳遞數據,以及后端如何接收數據的過程和方法之后。我突然發現,前端頁面寫的太難看了。俗話說“外行看熱鬧,內行看門道”。程序員寫的網站,在更多時候是給“外行”看的,他們可沒有耐心來看代碼,他們看的就是界面,因此界面是否做的漂亮一點點,是直觀重要的。 其實,也不僅僅是漂亮的原因,因為前端頁面,還要顯示從后端讀取出來的數據呢。 恰好,tornado提供比較好用的前端模板(tornado.template)。通過這個模板,能夠讓前端編寫更方便。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/306.md#render)render() render()方法能夠告訴tornado讀入哪個模板,插入其中的模板代碼,并返回結果給瀏覽器。比如在IndexHandler類中get()方法里面的`self.render("index.html")`,就是讓tornado到templates目中找到名為index.html的文件,讀出它的內容,返回給瀏覽器。這樣用戶就能看到index.html所規定的頁面了。當然,在前面所寫的index.html還僅僅是html標記,沒有顯示出所謂“模板”的作用。為此,將index.html和index.py文件做如下改造。 ~~~ #!/usr/bin/env python # coding=utf-8 import tornado.web import methods.readdb as mrd class IndexHandler(tornado.web.RequestHandler): def get(self): usernames = mrd.select_columns(table="users",column="username") one_user = usernames[0][0] self.render("index.html", user=one_user) ~~~ index.py文件中,只修改了get()方法,從數據庫中讀取用戶名,并且提出一個用戶(one_user),然后通過`self.render("index.html", user=one_user)`將這個用戶名放到index.html中,其中`user=one_user`的作用就是傳遞對象到模板。 提醒讀者注意的是,在上面的代碼中,我使用了`mrd.select_columns(table="users",column="username")`,也就是說必須要在methods目錄中的readdb.py文件中有一個名為select_columns的函數。為了使讀者能夠理解,貼出已經修改之后的readdb.py文件代碼,比上一節多了函數select_columns: ~~~ #!/usr/bin/env python # coding=utf-8 from db import * def select_table(table, column, condition, value ): sql = "select " + column + " from " + table + " where " + condition + "='" + value + "'" cur.execute(sql) lines = cur.fetchall() return lines def select_columns(table, column ): sql = "select " + column + " from " + table cur.execute(sql) lines = cur.fetchall() return lines ~~~ 下面是index.html修改后的代碼: ~~~ <!DOCTYPE html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Learning Python</title> </head> <body> <h2>登錄頁面</h2> <p>用用戶名為:{{user}}登錄</p> <form method="POST"> <p><span>UserName:</span><input type="text" id="username"/></p> <p><span>Password:</span><input type="password" id="password" /></p> <p><input type="BUTTON" value="登錄" id="login" /></p> </form> <script src="{{static_url("js/jquery.min.js")}}"></script> <script src="{{static_url("js/script.js")}}"></script> </body> ~~~ `<p>用用戶名為:{{user}}登錄</p>`,這里用了`{{ }}`方式,接受對應的變量引導來的對象。也就是在首頁打開之后,用戶應當看到有一行提示。如下圖一樣。 [![](https://box.kancloud.cn/2015-09-07_55ed5c12218e6.png)](https://github.com/qiwsir/StarterLearningPython/blob/master/3images/30601.png) 圖中箭頭是我為了強調后來加上去的,箭頭所指的,就是從數據庫中讀取出來的用戶名,借助于模板中的雙大括號`{{ }}`顯示出來。 `{{ }}`本質上是占位符。當這個html被執行的時候,這個位置會被一個具體的對象(例如上面就是字符串qiwsir)所替代。具體是哪個具體對象替代這個占位符,完全是由render()方法中關鍵詞來指定,也就是render()中的關鍵詞與模板中的占位符包裹著的關鍵詞一致。 用這種方式,修改一下用戶正確登錄之后的效果。要求用戶正確登錄之后,跳轉到另外一個頁面,并且在那個頁面中顯示出用戶的完整信息。 先修改url.py文件,在其中增加一些內容。完整代碼如下: ~~~ #!/usr/bin/env python # coding=utf-8 """ the url structure of website """ import sys reload(sys) sys.setdefaultencoding("utf-8") from handlers.index import IndexHandler from handlers.user import UserHandler url = [ (r'/', IndexHandler), (r'/user', UserHandler), ] ~~~ 然后就建立handlers/user.py文件,內容如下: ~~~ #!/usr/bin/env python # coding=utf-8 import tornado.web import methods.readdb as mrd class UserHandler(tornado.web.RequestHandler): def get(self): username = self.get_argument("user") user_infos = mrd.select_table(table="users",column="*",condition="username",value=username) self.render("user.html", users = user_infos) ~~~ 在get()中使用`self.get_argument("user")`,目的是要通過url獲取參數user的值。因此,當用戶登錄后,得到正確返回值,那么js應該用這樣的方式載入新的頁面。 注意:上述的user.py代碼為了簡單突出本將要說明的,沒有對user_infos的結果進行判斷。在實際的編程中,這要進行判斷或者使用try...except。 ~~~ $(document).ready(function(){ $("#login").click(function(){ var user = $("#username").val(); var pwd = $("#password").val(); var pd = {"username":user, "password":pwd}; $.ajax({ type:"post", url:"/", data:pd, cache:false, success:function(data){ window.location.href = "/user?user="+data; }, error:function(){ alert("error!"); }, }); }); }); ~~~ 接下來是user.html模板。注意上面的代碼中,user_infos引用的對象不是一個字符串了,也就是傳入模板的不是一個字符串,是一個元組。對此,模板這樣來處理它。 ~~~ <!DOCTYPE html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Learning Python</title> </head> <body> <h2>Your informations are:</h2> <ul> {% for one in users %} <li>username:{{one[1]}}</li> <li>password:{{one[2]}}</li> <li>email:{{one[3]}}</li> {% end %} </ul> </body> ~~~ 顯示的效果是: [![](https://box.kancloud.cn/2015-09-07_55ed5c2d972ed.png)](https://github.com/qiwsir/StarterLearningPython/blob/master/3images/30602.png) 在上面的模板中,其實用到了模板語法。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/306.md#模板語法)模板語法 在模板的雙大括號中,可以寫類似python的語句或者表達式。比如: ~~~ >>> from tornado.template import Template >>> print Template("{{ 3+4 }}").generate() 7 >>> print Template("{{ 'python'[0:2] }}").generate() py >>> print Template("{{ '-'.join(str(i) for i in range(10)) }}").generate() 0-1-2-3-4-5-6-7-8-9 ~~~ 意即如果在模板中,某個地方寫上`{{ 3+4 }}`,當那個模板被render()讀入之后,在頁面上該占位符的地方就顯示`7`。這說明tornado自動將雙大括號內的表達式進行計算,并將其結果以字符串的形式返回到瀏覽器輸出。 除了表達式之外,python的語句也可以在表達式中使用,包括if、for、while和try。只不過要有一個語句開始和結束的標記,用以區分那里是語句、哪里是HTML標記符。 語句的形式:`{{% 語句 %}}` 例如: ~~~ {{% if user=='qiwsir' %}} {{ user }} {{% end %}} ~~~ 上面的舉例中,第一行雖然是if語句,但是不要在后面寫冒號了。最后一行一定不能缺少,表示語句塊結束。將這一個語句塊放到模板中,當被render讀取此模板的時候,tornado將執行結果返回給瀏覽器顯示,跟前面的表達式一樣。實際的例子可以看上圖輸出結果和對應的循環語句。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/306.md#轉義字符)轉義字符 雖然讀者現在已經對字符轉義問題不陌生了,但是在網站開發中,它還將是一個令人感到麻煩的問題。所謂轉義字符(Escape Sequence)也稱字符實體(Character Entity),它的存在是因為在網頁中`<, >`之類的符號,是不能直接被輸出的,因為它們已經被用作了HTML標記符了,如果在網頁上用到它們,就要轉義。另外,也有一些字符在ASCII字符集中沒有定義(如版權符號“?”),這樣的符號要在HTML中出現,也需要轉義字符(如“?”對應的轉義字符是“&copy;”)。 上述是指前端頁面的字符轉義,其實不僅前端,在后端程序中,因為要讀寫數據庫,也會遇到字符轉義問題。 比如一個簡單的查詢語句:`select username, password from usertable where username='qiwsir'`,如果在登錄框中沒有輸入qiwsir,而是輸入了`a;drop database;`,這個查詢語句就變成了`select username, password from usertable where username=a; drop database;`,如果后端程序執行了這條語句會怎么樣呢?后果很嚴重,因為會`drop database`,屆時真的是欲哭無淚了。類似的情況還很多,比如還可以輸入`<input type="text" />`,結果出現了一個輸入框,如果是`<form action="..."`,會造成跨站攻擊了。這方面的問題還不少呢,讀者有空可以到網上搜一下所謂sql注入問題,能了解更多。 所以,后端也要轉義。 轉義是不是很麻煩呢? Tornado為你著想了,因為存在以上轉義問題,而且會有粗心的程序員忘記了,于是Tornado中,模板默認為自動轉義。這是多么好的設計呀。于是所有表單輸入的,你就不用擔心會遇到上述問題了。 為了能夠體會自動轉義,不妨在登錄框中輸入上面那樣字符,然后可以用print語句看一看,后臺得到了什么。 > print語句,在python3中是print()函數,在進行程序調試的時候非常有用。經常用它把要看個究竟的東西打印出來。 自動轉義是一個好事情,但是,有時候會不需要轉義,比如想在模板中這樣做: ~~~ <!DOCTYPE html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Learning Python</title> </head> <body> <h2>登錄頁面</h2> <p>用用戶名為:{{user}}登錄</p> <form method="POST"> <p><span>UserName:</span><input type="text" id="username"/></p> <p><span>Password:</span><input type="password" id="password" /></p> <p><input type="BUTTON" value="登錄" id="login" /></p> </form> {% set website = "<a href='http://www.itdiffer.com'>welcome to my website</a>" %} {{ website }} <script src="{{static_url("js/jquery.min.js")}}"></script> <script src="{{static_url("js/script.js")}}"></script> </body> ~~~ 這是index.html的代碼,我增加了`{% set website = "<a href='http://www.itdiffer.com'>welcome to my website</a>" %}`,作用是設置一個變量,名字是website,它對應的內容是一個做了超鏈接的文字。然后在下面使用這個變量`{{ website }}`,本希望能夠出現的是有一行字“welcome to my website”,點擊這行字,就可以打開對應鏈接的網站。可是,看到了這個: [![](https://box.kancloud.cn/2015-09-07_55ed5c3054c96.png)](https://github.com/qiwsir/StarterLearningPython/blob/master/3images/30603.png) 下面那一行,把整個源碼都顯示出來了。這就是因為自動轉義的結果。這里需要的是不轉義。于是可以將`{{ website }}`修改為: ~~~ {% raw website %} ~~~ 表示這一行不轉義。但是別的地方還是轉義的。這是一種最推薦的方法。 [![](https://box.kancloud.cn/2015-09-07_55ed5c3c6791f.png)](https://github.com/qiwsir/StarterLearningPython/blob/master/3images/30604.png) 如果你要全轉義,可以使用: ~~~ {% autoescape None %} {{ website }} ~~~ 貌似省事,但是我不推薦。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/306.md#幾個備查函數)幾個備查函數 下面幾個函數,放在這里備查,或許在某些時候用到。都是可以使用在模板中的。 * escape(s):替換字符串s中的&、為他們對應的HTML字符。 * url_escape(s):使用urllib.quote_plus替換字符串s中的字符為URL編碼形式。 * json_encode(val):將val編碼成JSON格式。 * squeeze(s):過濾字符串s,把連續的多個空白字符替換成一個空格。 此外,在模板中也可以使用自己編寫的函數。但不常用。所以本教程就不啰嗦這個了。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看