Python Web开发

来源:互联网 发布:淘宝有好货报名入口 编辑:程序博客网 时间:2024/06/06 00:11

1、Web应用的5个步骤
①用户在他所选择的Web浏览器中输入一个Web地址、选择一个超链接,或者点击一个按钮。
②Web浏览器将用户的动作转换为一个Web请求,并通过互联网把它发送到一个服务器。
③Web服务器收到Web请求,必须决定接下来做什么。
④Web服务器处理Web请求,创建一个Web响应,这会通过互联网发回给等待着的Web浏览器。
⑤第④步(可能)有很多子步骤
实际上第4步,可能包括很多子步骤,这要看Web服务器如何生成响应。如果服务器所要做的只是找到静态内容并把它发回给浏览器,那么这些子步骤不会太费劲,因为这些都只是文件I/O而已。
不过,如果必须生成动态内容,就要包括以下子步骤:Web服务器要找到所要执行的程序、执行找到的程序,然后捕获程序的输出作为Web响应……再把它发回给还在等待的Web浏览器。早在Web发展的初期,这个生成动态内容的过程已经得到标准化,称为通用网关接口(Common Gateway Interface,CGI)。符合标准的程序通常称为CGI脚本。
2、采用MVC设计Web应用
好的Web应用应当遵循模型-视图-控制器(Model-View-Controller)模式,这有助于将Web应用的代码分解为易于管理的功能模块(或组件):
模型:存储(以及有时处理)Web应用数据的代码。
视图:格式化和显示Web应用用户界面的代码。
控制器:将Web应用“粘合”在一起并提供业务逻辑的代码。
通过遵循MVC模式,可以合理构建你的Web应用,从而当出现新的需求时能够轻松扩展。另外还可以将工作分给多个人共同完成,每个人分别负责一个组件。
3、为数据建模
Web服务器需要存储数据的一个副本,在这里数据就是Kelly教练的计时值。启动这个Web应用时,需要把文本文件中的数据转换为AthleteList对象实例,存储在一个字典中(按选手名索引),然后保存为一个pickle文件。下面把这个功能放在一个名为put _ to _ store()的新函数中。在Web应用运行时,pickle文件中的数据可以作为一个字典应用使用。下面把这个功能放在另一个名为get _ from _store()的函数中。

class AthleteList(list):    def __init__(self,a_name,a_dob=None,a_times=[]):        list.__init__([])        self.name=a_name        self.dob=a_dob        self.extend(a_times)    def top3(self):        return(sorted(set([santize(each_time)for each_time in self]))[0:3])def get_coach_data(filename):    try:        with open(filename) as f:            data=f.readline()        temp1=data.strip().split(',')        return AthleteList(temp1.pop(0),temp1.pop(0),temp1)    except IOError as err:        print('File error:'+str(err))        return(None)def santize(time_item):        if '-' in time_item:            splits='-'        elif ':' in time_item:            splits=':'        else:            return time_item        (mins,secs)=time_item.split(splits)        return(mins+'.'+secs)import picklefrom athletelist import AthleteListdef get_coach_data(filename):    try:        with open(filename) as f:            data=f.readline()        temp1=data.strip().split(',')        return AthleteList(temp1.pop(0),temp1.pop(0),temp1)    except IOError as err:        print('File error:'+str(err))        return(None)def put_to_store(files_list):    all_athletes={}    for each_file in files_list:        ath=get_coach_data(each_file)        all_athletes[ath.name]=ath    try:        with open('athletes.pickle','wb') as athf:            pickle.dump(all_athletes,athf)    except IOError as ioerr:        print('File error(put_to_store):'+str(ioerr))    return (all_athletes)def get_from_store():    all_athletes={}    try:        with open('athletes.pickle','rb') as athf:            all_athletes=pickle.load(athf)    except IOError as ioerr:        print('File error(get_from_store):'+str(ioerr))    return (all_athletes)'''下面来测试代码,确保它能满足要求,F5执行,以下是在IDLE窗口键入的'''>>> the_files=['sarah2.txt','james2.txt','mikey2.txt','julie2.txt']>>> data=put_to_store(the_files)>>> data{'Sarah Sweeney': ['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55', '2:22', '2-21', '2.22'], 'James Lee': ['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22', '2-01', '2.01', '2:16'], 'Mikey McManus': ['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38', '2:40', '2.22', '2-31'], 'Julie Jones': ['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21', '3.01', '3.02', '2:59']}>>> for each_athlete in data:    print(data[each_athlete].name+' '+data[each_athlete].dob)Sarah Sweeney 2002-6-17James Lee 2002-3-14Mikey McManus 2002-2-24Julie Jones 2002-8-17>>> data_copy=get_from_store()>>> for each_data in data_copy:    print(data_copy[each_data].name+' '+data_copy[each_data].dob)Sarah Sweeney 2002-6-17James Lee 2002-3-14Mikey McManus 2002-2-24Julie Jones 2002-8-17

4、查看界面
上面已经编写了模型代码,下面来看看视图代码,这会创建Web应用的用户界面。在Web上,用户界面用Web的标记技术HTML来创建。
YATE另外一个模板引擎

from string import Templatedef start_response(resp="text/html"):    return('Content-type: ' + resp + '\n\n')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))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>&nbsp;&nbsp;&nbsp;&nbsp;'    footer = Template(foot_text)    return(footer.substitute(links=link_string))def start_form(the_url, form_type="POST"):    return('<form action="' + the_url + '" method="' + form_type + '">')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>') 

5、控制你的代码
模型代码已经准备好,而且用yate模块帮助建立视图代码,现在该用控制器代码把它们粘合在一起了。
首要的事情是你要合理的安排Web代码的目录结构,保证它有条理有组织,这样有利于以后增强扩展Web应用的能力。
这里写图片描述
6、CGI让Web服务器运行程序
通用网关接口(CGI)是一个Internet标准,允许Web服务器运行一个服务器端程序,称为CGI脚本。一般的CGI脚本放在cgi-bin的特殊文件夹下,这样Web服务器才能知道哪里找到CGI脚本,有些操作系统中(主要是类UNIX的系统),CGI脚本必须先设置为可执行,Web服务器才能执行这些脚本对Web请求做出响应。
实际上这个世界上的所有Web服务器都支持CGI脚本,但在这里使用有些大材小用了,好在,Python提供了它自己的Web服务器,这个Web服务器包含在http.server库模块中。请查看webapp.zip下载包的内容:它提供了一个支持CGI的Web服务器,名为simple_httpd.py

'''用python构建web服务器必须有这5行代码'''from http.server import HTTPServer, CGIHTTPRequestHandler'''导入http服务器和CGI模块'''port = 8080'''指定一个端口'''httpd = HTTPServer(('', port), CGIHTTPRequestHandler)'''创建http服务器'''print("Starting simple_httpd on port: " + str(httpd.server_port))httpd.serve_forever()'''显示友好的消息并启动服务器'''

7、显示选手列表
这里写图片描述
创建一个名为generate_list.py的程序

import athletemodelimport yateimport glob'''利用glob可以向操作系统查询一个文件名列表'''data_files=glob.glob("data/*.txt")athletes=athletemodel.put_to_store(data_files)print(yate.start_response())print(yate.include_header("Coach Kelly's List of Athletes"))print(yate.start_form("generate_timing_data.py"))print(yate.para("Selecct an athlete from the list to work with:"))for each_athlete in athletes:    print(yate.radio_button("which_athlete",athletes[each_athlete].name))print(yate.end_form("Select"))print(yate.include_footer({"Home":"/index.html"}))

8、创建另一个CGI脚本generate _ timing_data.py
生成一个新的HTML页面,其中包含所选选手的前3个时间。
这里写图片描述

import athletemodelimport yateimport cgiimport cgitbcgitb.enable()athletes=athletemodel.get_from_store()form_data=cgi.FieldStorage()'''获取所有表单数据,并放在一个字典中'''athlete_name=form_data['which_athlete'].valueprint(yate.start_response())print(yate.include_header("Coach Kelly's Timing Data"))print(yate.header("Athlete:"+athlete_name+",DOB:"+athletes[athlete_name].dob+"."))print(yate.para("The top times for this athlete are:"))print(yate.u_list(athletes[athlete_name].top3))print(yate.include_footer({"Home":"/index.html","select another athlete":"generate_list.py"}))

9、测试驱动
为了测试CGI脚本,需要启动一个Web服务器并运行。
从webapp文件夹打开一个命令窗口,启动你的web服务器:
python.exe simplehttpd.py
这里写图片描述
然后在浏览器上访问:http://127.0.0.1:8080
这里写图片描述
这里写图片描述
这里写图片描述
10、启用CGI跟踪来帮助解决错误
在CGI脚本前面增加这两行代码启用python的cgi跟踪技术:
import cgitb
cgitb.enable()
注:
如果一个方法使用了@property修饰符,那么这个方法会被看成是一个类属性,所以访问的时候不必加括号了

原创粉丝点击