head first python选读(5)
python web 开发
犯了低级错误,这本书看了一半了才知道书名应为《head first python》,不是hand first..
现在开始一个web应用。
总算是熟悉的内容了。但项目的总体的配置还是有些麻烦的。
考虑到Kelly教练的不断变更的需求,现在需要开发一个网站。包括:
- 欢迎页面
- 选择选手
- 显示时间
MVC模式和架构
- M 模型:数据储存。你需要一个model模块,用一个函数比如set把txt文件读出来,变成一个pickle,所有数据放到一个字典里
- V 视图:前端界面
- C 控制:业务代码。用一个get方法把数据取出来!返回一个数据字典。
现在来思考架构吧:
在根目录下以下代码可在本地运行一个基于python的简单的http服务器
# 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可完成欢迎页的开发.
模型
模型有两个文件
# 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()
显然就可以找到原因所在了。
head first python选读(5)的更多相关文章
- hand first python 选读(2)
文件读取与异常 文件读取与判断 os模块是调用来处理文件的. 先从最原始的读取txt文件开始吧! 新建一个aaa.txt文档,键入如下英文名篇: Li Lei:"Hello,Han Meim ...
- hand first python 选读(1)
列表(list) 基本操作 比如说我要整理一个近期热映的电影列表: movies = ["venom", "My Neighbor Totor", " ...
- python之进程与线程
什么是操作系统 可能很多人都会说,我们平时装的windows7 windows10都是操作系统,没错,他们都是操作系统.还有没有其他的? 想想我们使用的手机,Google公司的Androi ...
- python之面相对象程序设计
一 面向对象的程序设计的由来 面向对象设计的由来见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 面向对象的程序设计:路飞学院版 ...
- Python 中的实用数据挖掘
本文是 2014 年 12 月我在布拉格经济大学做的名为‘ Python 数据科学’讲座的笔记.欢迎通过 @RadimRehurek 进行提问和评论. 本次讲座的目的是展示一些关于机器学习的高级概念. ...
- Python基础-week06 面向对象编程基础
一.面向对象编程 1.面向过程 与 面向对象编程 面向过程的程序设计: 核心是 过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式 ...
- 送书福利| Python 完全自学手册
前言 这里不讨论「能不能学,要不要学,应不应该学 Python」的问题,这里只会告诉你怎么学. 首先需要强调的是,如果 Python 都学不会,那么我建议你考虑别的行业,因为 Python 之简单,令 ...
- Python 爬虫系列
爬虫简介 网络爬虫 爬虫指在使用程序模拟浏览器向服务端发出网络请求,以便获取服务端返回的内容. 但这些内容可能涉及到一些机密信息,所以爬虫领域目前来讲是属于灰色领域,切勿违法犯罪. 爬虫本身作为一门技 ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
随机推荐
- CentOS 6下OpenCV的安装与配置
自己按照网上的教程一步一步来的 http://www.jb51.net/os/RedHat/280309.html 虚拟机环境 CentOS 6.5 内核版本:4.1.14 64位 gcc,gcc 4 ...
- list_for_each_entry解析
双向链表及链表头: 建立一个双向链表通常有一个独立的用于管理链表的链表头,链表头一般是不含有实体数据的,必须用INIT_LIST_HEAD()进行初始化,表头建立以后,就可以将带有数据结构的实体链表成 ...
- PAT 1086 Tree Traversals Again[中序转后序][难]
1086 Tree Traversals Again(25 分) An inorder binary tree traversal can be implemented in a non-recurs ...
- Selenium+Python学习之一
刚入门selenium+Python,实验成功之后,记录一下过程. 首先是在知乎上面看到一个关于selenium+python的示例,于是自己便尝试搭建环境上手实验. 按照作者的代码敲一遍之后执行,竟 ...
- 马尔可夫随机场(Markov random fields) 概率无向图模型 马尔科夫网(Markov network)
上面两篇博客,解释了概率有向图(贝叶斯网),和用其解释条件独立.本篇将研究马尔可夫随机场(Markov random fields),也叫无向图模型,或称为马尔科夫网(Markov network) ...
- 如何用meavn构建mahout项目
(1)下载meavn 解压到D盘
- Java基础知识陷阱(六)
本文发表于本人博客. 上次说了下equals跟==的问题,今天再来认识一下这个equals()跟hasCode().上次的代码如下: class Person{ public String name; ...
- 如何使用iClap进行产品管理?
iClap概述: iClap是DevStore的全新产品,于2015年8月29号上线,该款产品专注于为移动互联网企业提供企业规范化解决方案,颠覆传统的产品管理模式,实现产品管理场景化.APP.甚至原型 ...
- Salesforce视图与控制器之间的交互
刚接触Salesforce,过程的确是比较艰难了,中文资料几乎没有,看英文资料学的效率却不高,不过看了一段时间的英文资料发现自己英语水平挺高不少啊,现在看都不用工具翻译,早知道就再次尝试报个6级,看下 ...
- OpenStack学习(一)
学习主要参考博文:https://www.cnblogs.com/CloudMan6/p/5233484.html 这个系列,,这里只是列出自己实际操作碰到的问题 一.安装系统:ubuntu 16.0 ...