摘要:也就是說用于設定與處理類間的映射關系。在中,默認使用和函數分別處理兩種請求。因為表單仍提交到當前頁面,所以還是由處理。載入時間相關的的一個類,獲取當前時間戳。獲取數據庫中的名為的。
前面的話
Demo1是一個簡單的博客系統(=。=什么網站都叫系統)。我們從這個簡單的系統入手,去了解P+T+M網站的內部邏輯,并記住一些“規則”,方便我們進一步自己開發。
“規則”這個詞特意打上了雙引號,目的是想借此聲明一點:本教程內不會將各語句背后的原理逐一講明(事實上我也講不清楚哈哈)。我的著重點將在“怎樣快速學會使用這個‘框架’去搭建我們想要的網站”,即“怎樣快速上手一個工具”。由于本人在技術上研究不深入不細致,所以用詞或者內容上難免有不規范或錯誤之處,能理解的就自行理解哈。當然愿意斧正的歡迎指出。
對了,本教程默認讀者是有web開發基礎的,明白“渲染”、“get請求”、“post請求”等分別是什么意思。
講解模式基本的是:
列出項目目錄結構
展示源碼,通過部分源碼注釋(紅色字)講解
列表項目
根據網站邏輯結合“代碼回顧”進行講解
希望大家復制源碼(記得把紅字注釋刪除)根據項目目錄結構創建項目,或者直接將附件中的代碼包拷到你的項目目錄,跟著講解一步一步試驗。
OK,開始。
Demo1項目目錄結構demo1 demo.py -static -css style.css -img bg.jpg logo.png -templates index.html blog.html源碼
demo.py
#!/usr/bin/env python # -*- coding: utf-8 -*- #用于規定字符編碼,想要中文正常最好就加上這句 import os.path import tornado.auth import tornado.escape import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options #巴拉巴拉import一大堆tornado的東西,反正都有用,原封不動即可 import pymongo #這里是導入MongoDB define(“port”, default=8002, help=”run on the given port”, type=int) #定義監聽的端口,隨便挑個喜歡的數字吧 class Application(tornado.web.Application): def __init__(self): handlers = [ (r”/”, MainHandler), (r”/blog”, BlogHandler), ] settings = dict( template_path=os.path.join(os.path.dirname(__file__), “templates”), static_path=os.path.join(os.path.dirname(__file__), “static”), debug=True, ) conn = pymongo.Connection(“localhost”, 12345) self.db = conn[“demo”] tornado.web.Application.__init__(self, handlers, **settings) class MainHandler(tornado.web.RequestHandler): def get(self): self.render(“index.html”,) def post(self): import time title = self.get_argument(‘title’, None) content = self.get_argument(‘content’, None) blog = dict() if title and content: blog[‘title’] = title blog[‘content’] = content blog[‘date’] = int(time.time()) coll = self.application.db.blog coll.insert(blog) self.redirect(‘/blog’) self.redirect(‘/’) class BlogHandler(tornado.web.RequestHandler): def get(self): coll = self.application.db.blog blog = coll.find_one() if blog: self.render(“blog.html”, page_title = blog[‘title’], blog = blog, ) else: self.redirect(‘/’) def main(): tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() if __name__ == “__main__”: main()
index.html
B06 Innovation Space 文章正文:
blog.html
部署項目{{ page_title }} 歡迎訪問B06創新實驗室的博客
{{ blog[‘title’] }} {{ locale.format_date(blog[‘date’], relative=False) }}
{{ blog[‘content’] }}
從頭開始說。
部署用Python開發的網站,需要在服務器上運行一個主文件,比如demo1的部署:
打開終端,cd到項目文件夾,執行python demo.py命令,此時python就在設定好的默認端口8002運行了我們這個網站。
代碼回顧:
define(“port”, default=8002, help=”run on the given port”, type=int)
此時打開瀏覽器,訪問http://127.0.0.1:8002,我們可以發現網站已經可以正常訪問。
再看終端窗口,發現已經接收到了一個get請求。
服務器是怎么樣根據我們的請求然后輸出給我們相應頁面的呢?
代碼回顧:
class Application(tornado.web.Application): def __init__(self): handlers = [ (r”/”, MainHandler), (r”/blog”, BlogHandler), ] settings = dict( template_path=os.path.join(os.path.dirname(__file__), “templates”), static_path=os.path.join(os.path.dirname(__file__), “static”), debug=True, ) conn = pymongo.Connection(“localhost”, 12345) self.db = conn[“demo”] tornado.web.Application.__init__(self, handlers, **settings)
我們看到在Application中初始化了兩個東西(數據庫連接另說),分別是handlers和settings。
顧名思義settings就是項目的各種設置,其中template_path用于指定我們之后要渲染的html文件的文件夾位置,而static_path用于指定之后要用的的一些引用文件(如css文件、js文件、圖片等)的文件夾位置 (我偏不解釋debug是干什么的:-) )。
handler,我百度翻譯了一下,是“處理者”的意思。它的作用就是處理我們向服務器提交的請求。怎么處理呢?
以(r”/”, MainHandler)為例,雙引號中間是要訪問頁面的相對路徑,而后面的XxxHandler表示這個路徑對應的“處理者類”。初始化如上handlers后,當我們訪問http://127.0.0.1:8002/時,我們的請求會被交給MainHandler處理;同樣的,當我們訪問http://127.0.0.1:8002/blog時,我們的請求將會被交給BlogHandler處理。也就是說handlers用于設定url與處理類間的映射關系。
在之后的幾個demo里面,通過對更多handler的設置,我們會慢慢對handler了解得更清楚一些,不要著急。反正大概意思就是一個網址對應一個handler唄。
數據庫連接代碼回顧:
class Application(tornado.web.Application): …… conn = pymongo.Connection(“localhost”, 12345) self.db = conn[“demo”] tornado.web.Application.__init__(self, handlers, **settings)
然后說一下這個部分。聰明的人一看就知道這是數據庫連接嘛。
第一句:參數一,數據庫服務器地址,我們現在是本地服務器所以用localhost;參數二,端口號,端口號當然是你本地MongoDB使用的端口號。這樣就連接上MongoDB了。
第二句:self.db = conn[“demo”],選擇一個數據庫,把數據庫名字放在雙引號中間。我的數據庫就叫做demo。最后一句就是把之前的設置都初始化嘛,init就是初始化,聰明人都懂的。
服務器處理請求OK,回過頭來,剛才說到當用戶訪問一個頁面的時候,根據我們初始化的handler,服務器會將不同的請求分發給不同的處理類進行處理。
我們的Demo1包含兩個頁面。首頁有一個表單,提交表單后跳轉至博客頁面。我們先來看看訪問首頁時是怎么處理的。
當我們訪問http://127.0.0.1:8002/時,我們的請求會被交給MainHandler處理,即執行這個類里對應的內容。
代碼回顧:
class MainHandler(tornado.web.RequestHandler):
處理類的定義規則是class XxxxHandler(tornado.web.RequestHandler)。Request請求,Handler處理者,處理請求的一個類嘛。括號里面的東西肯定跟tornado、跟網絡什么的有關,乖乖地復制就好了。
代碼回顧:
def get(self):#用于處理get請求,默認參數是self self.render(“index.html”,) def post(self):#用于處理post請求,默認參數是self import time title = self.get_argument(‘title’, None) content = self.get_argument(‘content’, None) blog = dict() if title or content: blog[‘title’] = title blog[‘content’] = content blog[‘date’] = int(time.time()) coll = self.application.db.blog coll.insert(blog) self.redirect(‘/blog/’) self.redirect(‘/’)
我們看到MainHandler類里定義了get和post兩個方法。
學習tornado讓我很感動的一點就是,它讓我明白了其實我們在訪問網頁的時候歸根結底就是向網站發出了兩種請求(這個認識可能比較淺薄)。
一種是get請求,即打開某個頁面。
另一種是post請求,即向某個頁面提交表單(數據)。
在tornado中,默認使用get和post函數分別處理兩種請求。所以當我們訪問http://127.0.0.1:8002/時,服務器就會執行MainHandler中的get函數。
代碼回顧:
def get(self): self.render(“index.html”,)
render就是渲染的意思。這一句就是:在瀏覽器中渲染出index.html這個文件的內容。index.html文件在哪里呢?從項目目錄結構中可以看到,它在templates文件夾中。還記得settings中定義的templates_path嗎?我們在render()中的雙引號內填入templates文件夾中文件的相對路徑即可,服務器會根據templates_path自動補全路徑,找到文件,并將之渲染出來。
插一句:在用tornado開發時,我們常用的目錄結構正如demo1的目錄結構。根目錄下放置python文件,templates文件夾中放置html文件,static文件夾中放置引用文件。
所以,當我們訪問http://127.0.0.1:8002/時,最終看到的就是下圖:
代碼回顧:
此時,我們看到了首頁的表單。來看看index.html的源碼:表單的提交方式是post;請求的頁面(action)沒有填寫,表示提交到當前頁面。現在將表單填充,點擊發布。
此時查看終端窗口,我們發現,服務器收到了一個post請求。
因為表單仍提交到當前頁面,所以還是由MainHandler處理。而此時的請求類型為post,所以服務器將執行MainHandler中的post方法。
代碼回顧:
def post(self): import time title = self.get_argument(‘title’, None) content = self.get_argument(‘content’, None) blog = dict() if title and content: blog[‘title’] = title blog[‘content’] = content blog[‘date’] = int(time.time()) coll = self.application.db.blog coll.insert(blog) self.redirect(‘/blog’)
tornado中通過self.get_argument()獲取表單數據,其中第一個參數為數據名稱,第二個參數為當沒有獲取到該表單數據時的替代值。
post方法分別獲取表單中title和content兩個數據,進行簡單的判斷,當二者均不為空時,將其存入預定義的blog變量中,并且給blog[‘date’]賦值為當前的時間戳。
import time載入時間相關的的一個類,time.time()獲取當前時間戳。 coll = self.application.db.blog獲取數據庫中的名為blog的collection。
coll.insert(blog)將blog變量插入collection中。
self.redirect(‘/blog’)頁面跳轉至博客頁。在使用redirect函數時,參數為頁面相對路徑。
簡單來說:post方法接收了表單數據并將其插入對應數據集中,然后頁面跳轉到博客頁。
頁面跳轉,本質就是訪問跳轉后的頁面,即向此頁面發送get請求。我們看一下終端窗口:
也就是說self.redirect(‘/blog’)這一句,就是訪問http://127.0.0.1:8002/blog,服務器得到get請求,然后讓BlogHandler對其進行處理,執行get方法。
代碼回顧:
def get(self): coll = self.application.db.blog blog = coll.find_one() if blog: self.render(“blog.html”, page_title = blog[‘title’], blog = blog, ) else: self.redirect(‘/’)
那我們看看函數內容。
coll = self.application.db.blog依舊是獲取名字為blog的數據集 blog = coll.find_one()獲取一條數據。因為我們是一個最簡版的demo,所以就獲取一條數據。
if判斷數據是否存在,存在則渲染博客頁面,不存在則跳轉至首頁。
render函數第一個參數是要渲染的html文件名,后面的參數為傳遞到頁面的數據,參數間用逗號隔開。
page_title = blog[‘title’]我選擇用博客標題作為title,所以傳了一個page_title過去。 blog = blog把博客內容傳遞過去。
什么叫把數據傳遞到html文件去呢?就是把我們動態獲取的數據庫數據和html文件一起渲染,把數據在html代碼中輸出來。
For一個sample:-):
代碼回顧:
{{ blog[‘title’] }} {{ locale.format_date(blog[‘date’], relative=False) }}
{{ blog[‘content’] }}
在html文件中可以通過特殊語法輸出我們傳遞過來的數據。
{{ 變量名 }},雙大括號中加上變量名,就是輸出該變量。比如:{{ blog[‘title’] }}就是輸出blog中的title值;{{blog[‘content’] }}就是輸出blog中的content值;還有{{ page_title }}就是輸出page_title的值。
(關于Tornado在html文件里面對Python語句的使用方法,我會在另外一篇總結中寫出來。鏈接:《Tornado,在模板里使用Python語句》)
locale.format_date()是一個時間格式化函數。locale.format_date(blog[‘date’], relative=False) }}是將blog[‘date’]的值格式化輸出。
所以最終渲染出的頁面如下圖:
至此,一個最簡單的博客系統就完成了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/18734.html
摘要:接下來判斷是否為空。因此接下來執行。這個方法用于獲取字典中指定鍵名的鍵值第一個參數,如果該鍵名不存在,則返回第二個參數設定的默認值。當我們填寫好表單,點擊發布按鈕,表單就以方式被提交到相對路徑,對應的絕對路徑為。 前面的話 在Demo1里面,我們練習了如何部署應用、tornado框架的基本結構以及應用如何處理請求。 其實Demo1算不上一個博客啦。一個最基本的信息系統一定要包含對數據...
摘要:接下來判斷是否為空。因此接下來執行。這個方法用于獲取字典中指定鍵名的鍵值第一個參數,如果該鍵名不存在,則返回第二個參數設定的默認值。當我們填寫好表單,點擊發布按鈕,表單就以方式被提交到相對路徑,對應的絕對路徑為。 前面的話 在Demo1里面,我們練習了如何部署應用、tornado框架的基本結構以及應用如何處理請求。 其實Demo1算不上一個博客啦。一個最基本的信息系統一定要包含對數據...
摘要:學習筆記七數學形態學關注的是圖像中的形狀,它提供了一些方法用于檢測形狀和改變形狀。學習筆記十一尺度不變特征變換,簡稱是圖像局部特征提取的現代方法基于區域圖像塊的分析。本文的目的是簡明扼要地說明的編碼機制,并給出一些建議。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 開始之前,我們先來看這樣一個提問: pyth...
摘要:如果你使用而不是硬編碼的話,你的代碼不需要改變。如果你在每個引用靜態資源的文件中硬編碼靜態路徑部分,你將不得不手動修改每個模板。 我相信當你在看這篇文章的時候,你一定已經了解了 模板Templates 這個概念。 在Tornado Web應用中使用render方法傳送HTML給瀏覽器,即將模板在瀏覽器中渲染出來。 我們知道render函數參數包含兩個部分:第一個部分是模板文件。我們...
閱讀 2485·2021-11-24 09:39
閱讀 3528·2019-08-30 15:53
閱讀 602·2019-08-29 15:15
閱讀 2909·2019-08-26 13:23
閱讀 3224·2019-08-26 10:48
閱讀 650·2019-08-26 10:31
閱讀 776·2019-08-26 10:30
閱讀 2370·2019-08-23 18:32