如果像前面那么做網站,也太丑陋了。并且功能也不多。
在實際做網站中,現在都要使用一個模板,并且在用戶直接看到的頁面,用html語言來寫頁面(關于HTML,本教程默認為看官已經熟悉,如果不熟悉,可以到找有關教程來學習)。
在做網站的行業里面,常常將HTML+CSS+JS組成的網頁,稱作“前端”。它主要負責展示,或者讓用戶填寫一些表格,通過JS提交給用python寫的程序,讓python程序來處理數據,那些處理數據的python程序稱之為“后端”。我常常提醒做“后端”的,不要輕視“前端”。如果看官立志成為全棧工程師,就要從前到后都通。
在本講中,為了突出模板和后端程序,我略去CSS+JS,雖然這樣一來界面難看,而且用戶的友好度也不怎么樣(JS,javascript是使網頁變得更友好的重要工具,如不用更換地址就能刷新頁面等等,特別提醒看官,一定要學好javascript,雖然這個可能沒有幾個大學教的。請看維基百科對javascript簡介:)。
> JavaScript,一種直譯式腳本語言,是一種動態類型、弱類型、基于原型的語言,內置支持類。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用于客戶端的腳本語言,最早是在HTML網頁上使用,用來給HTML網頁增加動態功能。然而現在JavaScript也可被用于網絡服務器,如Node.js。
>
> 在1995年時,由網景公司的布蘭登·艾克,在網景導航者瀏覽器上首次設計實作而成。因為網景公司與升陽公司合作,網景公司管理層次結構希望它外觀看起來像Java,因此取名為JavaScript。但實際上它的語法風格與Self及Scheme較為接近。
>
> 為了取得技術優勢,微軟推出了JScript,CEnvi推出ScriptEase,與JavaScript同樣可在瀏覽器上運行。為了統一規格,1997年,在ECMA(歐洲計算機制造商協會)的協調下,由Netscape、Sun、微軟、Borland組成的工作組確定統一標準:ECMA-262。因為JavaScript兼容于ECMA標準,因此也稱為ECMAScript。
上面這段引文里面提到了一個非常著名的公司:網景,可能年青一代都忘卻了。也建議有興趣的看官到維基百科中了解這個傳奇公司,它曾經有一個傳奇產品,雖然名字不復存在,但是Firefox是秉承它衣缽的。
話題再轉回來,還是關于本講,主要是要演示一個用模板(HTML)寫一個表單,然后提交給后端的python程序,再轉到另外一個顯示的前端頁面顯示。為了簡化流程,這個過程中沒有數據處理和CSS+Javascript的工作,所有界面會丑陋。但是,“我很丑,可是我很溫柔”。
## 一個表單
要做一個前端的頁面,顯示的內容就如同下圖樣式
[](https://github.com/qiwsir/ITArticles/blob/master/Pictures/31101.png)
相應代碼是,并命名為index.html,存在一個名稱是template的目錄中。
~~~
<!DOCTYPE html>
<html>
<head>
<title>sign in your name</title>
</head>
<body>
<h2>Please sing in.</h2>
<form method="post" action="/user">
<p>Name:<br><input type="text" name="username"></p>
<p>Email:<br><input type="text" name="email"></p>
<p>Website:<br><input type="text" name="website"></p>
<p>Language:<br><input type="text" name="language"></p>
<input type="submit" value="ok,submit my information">
</form>
</body>
</html>
~~~
上面的代碼是比較簡單,如果看官熟悉html的話,不熟悉也不要緊,網上搜索就能理解。注意,沒有CSS+JS,所以簡單。如果在真正開發中,這兩個是不能少的。
有了這個表單之后,如果用戶把相關信息都填寫好了。點擊下面的按鈕,就應該提交給后端的python程序來處理。
## 后端處理程序
做為tornado驅動的網站,首先要能夠把前面的index.html顯示出來,這個一般用get方法,顯示的樣式就按照上面的樣子顯示。
用戶填寫信息之后,點擊按鈕提交。注意觀察上面的代碼表單中,設定了`post`方法,所以,在python程序中,應該有一個post方法專門來接收所提交的數據,然后把提交的數據在另外一個網頁顯示出來。
在表單中還要注意,有一個`action=/user`,表示的是要將表單的內容提交給`/user`路徑所對應的程序來處理。這里需要說明的是,在網站中,數據提交和顯示,路徑是非常重要的。
按照以上意圖,編寫如下代碼,并命名為usercontroller.py,保存在template目錄中
~~~
#!/usr/bin/env python
#coding:utf-8
import os.path
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
class UserHandler(tornado.web.RequestHandler):
def post(self):
user_name = self.get_argument("username")
user_email = self.get_argument("email")
user_website = self.get_argument("website")
user_language = self.get_argument("language")
self.render("user.html",username=user_name,email=user_email,website=user_website,language=user_language)
handlers = [
(r"/", IndexHandler),
(r"/user", UserHandler)
]
template_path = os.path.join(os.path.dirname(__file__),"template")
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(handlers, template_path)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
~~~
這次代碼量多一些。但是多數在前面講述tornado基本結構的時候已經說過了,跟前面一樣,這里僅僅把重點的和新出現的進行講述,如果看官對某些內容還有疑問,可以參考前面的相關章節。
在引入的模塊上,多了一個`import os.path`,這個模塊主要用在:
~~~
template_path = os.path.join(os.path.dirname(__file),"template")
~~~
這是要獲取存放程序的目錄`template`的路徑。
重點看兩個類中都有的`self.render()`,用這個方法引入相應的模板。
~~~
self.render("index.html")
~~~
顯示index.html模板,但是此時并沒有向模板網頁傳遞任何數據,僅僅顯示罷了。下面一個:
~~~
self.render("user.html",username=user_name,email=user_email,website=user_website,language=user_language)
~~~
與前面的不同在于,不僅僅是要引用模板網頁user.html,還要向這個網頁傳遞一些數據,例如username=user_name,含義就是,在模板中,某個地方是用username來標示得到的數據,而user_name是此方法中的一個變量,也就是對應一個數據,那么模板中的username也就對應了user_name的數據,這是通過username=user_name完成的(說的有點像外語了)。后面的變量同理。
那么,user_name的數據是哪里來的呢?就是在index.html頁面的表單中提交上來的。注意觀察路徑的設置,`r"/user", UserHandler`,也就是在form中的`action='/user'`,就是要將數據提交給UserHandler處理,并且是通過post方法。所以,在UserHandler類中,有post()方法來處理這個問題。通過self.get_argument()來接收前端提交過來的數據,接收方法就是,self.get_argument()的參數與index.html表單form中的各項的name值相同,就會得到相應的數據。例如`user_name = self.get_argument("username")`,就能夠得到index.html表單中name為"username"的元素的值,并賦給user_name變量。
還差一個網頁。
## 顯示結果
在上面的代碼中,又多了一個模板:`index.html`,對這個模板,跟前面那個模板有一點兒不一樣的地方,就是要引入一些變量。它的代碼是這樣的:
~~~
<!DOCTYPE html>
<html>
<head>
<title>sign in your name</title>
</head>
<body>
<h2>Your Information</h2>
<p>Your name is {{username}}</p>
<p>Your email is {{email}}</p>
<p>Your website is {{website}}, it is very good. This website is make by {{language}}</p>
</body>
</html>
~~~
請將上面的代碼和這句話對照:
~~~
self.render("user.html",username=user_name,email=user_email,website=user_website,language=user_language)
~~~
上面的模板代碼存儲為名為`user.html`的文件,并且和前面已經保存的在同一個目錄中。
看HTML模板代碼中,有類似`{{username}}`的變量,模板中用`{{}}`引入變量,這個變量就是在`self.render()`中規定的,兩者變量名稱一致,對應將相應的值對象引入到模板中。
## 運行結果
進入到template目錄,執行:
~~~
qw@qw-Latitude-E4300:~/template$ python userscontroller.py
~~~
然后在瀏覽器的地址欄中輸入
~~~
http://localhost:8000
~~~
出現如下圖的表單,并填寫表單內容
[](https://github.com/qiwsir/ITArticles/blob/master/Pictures/31102.png)
點擊“按鈕”之后:
[](https://github.com/qiwsir/ITArticles/blob/master/Pictures/31103.png)
這樣就實現了一個簡單表單提交的網站。
- 第零部分 獨上高樓,望盡天涯路
- 嘮叨一些關于Python的事情
- 為什么要開設本欄目
- 第一部分 積小流,至江海
- Python環境安裝
- 集成開發環境(IDE)
- 數的類型和四則運算
- 啰嗦的除法
- 開始真正編程
- 初識永遠強大的函數
- 玩轉字符串(1):基本概念、字符轉義、字符串連接、變量與字符串關系
- 玩轉字符串(2)
- 玩轉字符串(3)
- 眼花繚亂的運算符
- 從if開始語句的征程
- 一個免費的實驗室
- 有容乃大的list(1)
- 有容乃大的list(2)
- 有容乃大的list(3)
- 有容乃大的list(4)
- list和str比較
- 畫圈還不簡單嗎
- 再深點,更懂list
- 字典,你還記得嗎?
- 字典的操作方法
- 有點簡約的元組
- 一二三,集合了
- 集合的關系
- Python數據類型總結
- 深入變量和引用對象
- 賦值,簡單也不簡單
- 坑爹的字符編碼
- 做一個小游戲
- 不要紅頭文件(1): open, write, close
- 不要紅頭文件(2): os.stat, closed, mode, read, readlines, readline
- 第二部分 窮千里目,上一層樓
- 正規地說一句話
- print能干的事情
- 從格式化表達式到方法
- 復習if語句
- 用while來循環
- 難以想象的for
- 關于循環的小伎倆
- 讓人歡喜讓人憂的迭代
- 大話題小函數(1)
- 大話題小函數(2)
- python文檔
- 重回函數
- 變量和參數
- 總結參數的傳遞
- 傳說中的函數條規
- 關于類的基本認識
- 編寫類之一創建實例
- 編寫類之二方法
- 編寫類之三子類
- 編寫類之四再論繼承
- 命名空間
- 類的細節
- Import 模塊
- 模塊的加載
- 私有和專有
- 折騰一下目錄: os.path.<attribute>
- 第三部分 昨夜西風,亭臺誰登
- 網站的結構:網站組成、MySQL數據庫的安裝和配置、MySQL的運行
- 通過Python連接數據庫:安裝python-MySQLdb,連接MySQL
- 用Pyton操作數據庫(1):建立連接和游標,并insert and commit
- 用Python操作數據庫(2)
- 用Python操作數據庫(3)
- python開發框架:框架介紹、Tornado安裝
- Hello,第一個網頁分析:tornado網站的基本結構剖析:improt模塊、RequestHandler, HTTPServer, Application, IOLoop
- 實例分析get和post:get()通過URL得到數據和post()通過get_argument()獲取數據
- 問候世界:利用GAE建立tornado框架網站
- 使用表單和模板:tornado模板self.render和模板變量傳遞
- 模板中的語法:tornado模板中的for,if,set等語法
- 靜態文件以及一個項目框架
- 模板轉義
- 第四部分 暮然回首,燈火闌珊處
- requests庫
- 比較json/dictionary的庫
- defaultdict 模塊和 namedtuple 模塊
- 第五部分 Python備忘錄
- 基本的(字面量)值
- 運算符
- 常用的內建函數
- 擴展閱讀(來自網絡文章)
- 人生苦短,我用Python