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>&nbsp;&nbsp;&nbsp;&nbsp;'
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)的更多相关文章

  1. hand first python 选读(2)

    文件读取与异常 文件读取与判断 os模块是调用来处理文件的. 先从最原始的读取txt文件开始吧! 新建一个aaa.txt文档,键入如下英文名篇: Li Lei:"Hello,Han Meim ...

  2. hand first python 选读(1)

    列表(list) 基本操作 比如说我要整理一个近期热映的电影列表: movies = ["venom", "My Neighbor Totor", " ...

  3. python之进程与线程

    什么是操作系统       可能很多人都会说,我们平时装的windows7 windows10都是操作系统,没错,他们都是操作系统.还有没有其他的? 想想我们使用的手机,Google公司的Androi ...

  4. python之面相对象程序设计

    一 面向对象的程序设计的由来 面向对象设计的由来见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 面向对象的程序设计:路飞学院版 ...

  5. Python 中的实用数据挖掘

    本文是 2014 年 12 月我在布拉格经济大学做的名为‘ Python 数据科学’讲座的笔记.欢迎通过 @RadimRehurek 进行提问和评论. 本次讲座的目的是展示一些关于机器学习的高级概念. ...

  6. Python基础-week06 面向对象编程基础

    一.面向对象编程 1.面向过程 与 面向对象编程 面向过程的程序设计: 核心是 过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式 ...

  7. 送书福利| Python 完全自学手册

    前言 这里不讨论「能不能学,要不要学,应不应该学 Python」的问题,这里只会告诉你怎么学. 首先需要强调的是,如果 Python 都学不会,那么我建议你考虑别的行业,因为 Python 之简单,令 ...

  8. Python 爬虫系列

    爬虫简介 网络爬虫 爬虫指在使用程序模拟浏览器向服务端发出网络请求,以便获取服务端返回的内容. 但这些内容可能涉及到一些机密信息,所以爬虫领域目前来讲是属于灰色领域,切勿违法犯罪. 爬虫本身作为一门技 ...

  9. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

随机推荐

  1. 深入理解Flink核心技术(转载)

    作者:李呈祥 Flink项目是大数据处理领域最近冉冉升起的一颗新星,其不同于其他大数据项目的诸多特性吸引了越来越多的人关注Flink项目.本文将深入分析Flink一些关键的技术与特性,希望能够帮助读者 ...

  2. SpringMVC-SimpleDEMO

    本博文主要将如何配置一个简单的SpringMVC的DEMO,由上一讲的SpringMVC工作流程来看,配置一个SpringMVC的步骤是简单而清晰的. 一.引入SpringMVC所需依赖   < ...

  3. glib简单记录包括字符串,主循环,回调函数和xml解析

    一.将最近用到的glib字符串功能整理了下直接用程序记录比较好看懂 #define MAX_LEN 100gchar * demo (char* msg, ...){    gchar * pcfgf ...

  4. 关于softnet的加密硬件狗 也就是所谓的赛孚耐

    SuperDog-R-2.2.1.iso 上面那个文件就是光盘里面的东西.你买了他们的产品 自然后带着这个玩意. 按照默认路径安装一下. 安装完毕如下图:

  5. 无法从U盘启动的解决方案

    联想台式机无法从U盘启动的解决方案 F1进入lenovo bios 选择 StartUp 选项卡 1) 发现 USB FDD 已处于第一项,再把 USB Key 调到启动第二项 2) 把 boot m ...

  6. JavaScript:学习笔记(9)——Promise对象

    JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...

  7. XDU 1011

    解法1:TLE #include<stdio.h> int main() { long long n; //freopen("in.txt","r" ...

  8. ruby中的self

    self,自己,在ruby中表示当前对象或默认对象.程序执行的任一时刻,有且仅有一个self. 1.谁成为self,在什么位置成为self? 要知道哪个对象是self,就必须知道当前的上下文.上下文主 ...

  9. 运维自动化之salt笔记

    1:saltstack的基本介绍 2:salt的安装 1:服务端1:安装2:配置文件3:运行4:注意事项2:客户端1:安装2:配置文件3:运行4:注意事项 3:salt的使用: 1:基础知识1:tar ...

  10. 20. Valid Parentheses(括号匹配,用桟)

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...