犯了低級錯誤,這本書看了一半了才知道書名應爲《head first python》,不是hand first..css
如今開始一個web應用。html
總算是熟悉的內容了。但項目的整體的配置仍是有些麻煩的。前端
考慮到Kelly教練的不斷變動的需求,如今須要開發一個網站。包括:python
如今來思考架構吧:git
在根目錄下如下代碼可在本地運行一個基於python的簡單的http服務器web
# app.py from http.server import HTTPServer, CGIHTTPRequestHandler port = 8080 httpd = HTTPServer(('', port), CGIHTTPRequestHandler) print("Starting simple_httpd on port: " + str(httpd.server_port)) httpd.serve_forever()
這個app.py是全部文件的入口。所以全部的文件都依靠這個文件進行交互。路徑以根目錄爲主。服務器
看到這個就顯示成功了架構
添加index.html可完成歡迎頁的開發.mvc
模型有兩個文件app
# athletelist.py def sanitize(score): splitter = '.' if '-' in score: splitter = '-' if ':' in score: splitter = ':' elif '.' in splitter: return score (mins , sec) = score.split(splitter) return mins+'.'+sec class AthleteList(list): def __init__(self, a_name, a_birth=None, a_scores=[]): list.__init__(list([])) self.name = a_name self.birth = a_birth self.extend(a_scores) def top3(self): return sorted(set([sanitize(score) for score in self]))[0:3]
而後把邏輯寫好
# athleteModal.py import pickle from athletelist import AthleteList def get(filename): try: with open(filename) as data: line = data.readline() scores = line.split(',') return AthleteList(scores.pop(0), scores.pop(0), scores) except IOError as err: print('file error.'+str(err)) # 把讀取的數據轉化爲二進制文件,提供一個文件名列表做爲參數 def set_data(file_list): all_athletes={} for item in file_list: with open(item) as data: ath=get(item) all_athletes[ath.name]=ath try: pickle.dump(all_athletes,open('db','wb')) except IOError as ioerr: print('file err:'+str(ioerr)) print('set_data finished.') return all_athletes # 從二進制文件中讀取數據, def get_from_store(): all_athletes={} data=pickle.load(open('db','rb')) all_athletes=data print(all_athletes) return all_athletes set_data(['james.txt','julie.txt','sarah.txt','mickey.txt'])
看到了熟悉的JSON!
模板引擎會用到一些新的方法,在此須要讀懂。
from string import Template # 從內置的string庫導入Template類,可支持字符串替換模板 def start_response(resp="text/html"): return('Content-type: ' + resp + '\n\n') # 建立一個content-type:缺省爲text-html def include_header(the_title): with open('templates/header.html') as headf: head_text = headf.read() header = Template(head_text) return(header.substitute(title=the_title)) # 打開header.html,設置網站標題 def include_footer(the_links): with open('templates/footer.html') as footf: foot_text = footf.read() link_string = '' for key in the_links: link_string += '<a href="' + the_links[key] + '">' + key + '</a> ' footer = Template(foot_text) return(footer.substitute(links=link_string)) # 打開 footer文件,渲染腳部連接 def start_form(the_url, form_type="POST"): return('<form action="' + the_url + '" method="' + form_type + '">') # 生成一個post表單,表單跳轉action def end_form(submit_msg="Submit"): return('<p></p><input type=submit value="' + submit_msg + '"></form>') # 提交按鈕 def radio_button(rb_name, rb_value): return('<input type="radio" name="' + rb_name +'" value="' + rb_value + '"> ' + rb_value + '<br />') # 渲染單選框 def u_list(items): u_string = '<ul>' for item in items: u_string += '<li>' + item + '</li>' u_string += '</ul>' return(u_string) # 渲染無序列表 def header(header_text, header_level=2): return('<h' + str(header_level) + '>' + header_text + '</h' + str(header_level) + '>') # 渲染標題 def para(para_text): return('<p>' + para_text + '</p>') #渲染內容
前端模板怎麼響應這個cgi呢?簡單寫一下吧。用$
表示變量。
header:
<html> <head> <title>$title</title> <link type="text/css" rel="stylesheet" href="/coach.css" /> </head> <body> <h1>$title</h1>
footer:
<p> $links </p> </body> </html>
如今建立一個gen_liust.py
,要求執行選手時,生成一個選擇選手的頁面。你所要作的就是閱讀模板引擎文檔。
# gen_list.py # 建立選手列表 import athletemodel import fe import glob # glob可向操做系統查詢一個文件名列表 # 查詢,返回列表 data_files=glob.glob('data/*.txt') #讀取數據 athletemodel.set_data(data_files) athletes=athletemodel.get_from_store() print(fe.start_response()) print(fe.include_header('web_app')) print(fe.start_form('http://www.baidu.com')) print(fe.para('Select a athlete')) for athlete in athletes: print(fe.radio_button('select_athlete',athletes[athlete].name)) print(fe.end_form()) print(fe.include_footer({'home':'/index.html'}))
在首頁文件中,a標籤爲<a href="cgi-bin/gen_list.py">
便可跳轉相應的頁面。
顯示某人的計時數據和快捷連接。
獲取post上傳數據L
import cgi form_data=cgi
剩下的很好作了:
import cgi import fe import athletemodel athletes=athletemodel.get_from_store() #獲取表單數據並放到一個字典中 form_data=cgi.FieldStorage() athlete_name=form_data['name'].value # 渲染頁面 print(fe.start_response()) print(fe.include_header(athlete_name)) print(fe.u_list(athletes[athlete_name].top3())) print(fe.include_footer({'home':'/index.html','back':'gen_list.py'}))
若是我在表單啥子也不填就提交。就很難跟蹤錯誤所在.
實際開發過程當中,調bug會花費不少時間。應該想辦法在web服務器上友好地顯示錯誤信息。
import cgitb cgitb.enable()
顯然就能夠找到緣由所在了。