4w作业
作业要求
本周整体任务概述:
- 在上周开发基础上, 完成 极简交互式笔记的Web版本
- 需求如下:
- 通过网页访问系统:
- 每次运行时合理的打印出过往的所有笔记
- 一次接收输入一行笔记
- 在服务端保存为文件
- 同时兼容 3w 的 Net 版本的命令行界面进行交互
背景:
- 系统:mac os 10.10
- python:Python 2.7
- 编辑器:vim
- 终端:iTerm
安装bottle
官网 :http://bottlepy.org/docs/dev/tutorial.html
直接按照官网的下载
wget http://bottlepy.org/bottle.py
提示:
!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://github.com/defnull/bottle/raw/master/bottle.py">here</a>.</p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at bottlepy.org Port 80</address>
</body></html>
直接打开上面链接,跳转到另一个链接,用下面命令下载
curl -o bottle.py https://raw.githubusercontent.com/bottlepy/bottle/master/bottle.py
从hello world
开始
运行看看,找找感觉
from bottle import route, run
@route('/hello')
def hello():
return "Hello World!"
run(host='localhost', port=8080, debug=True)
- route():的函数是将一段代码绑定到URL上,上面的例子就是将hello()函数绑定到
/hello
的URL上,也就是直接定义URL - host跟port绑定ip个端口
- run() 启动服务
- debug=True 开启开发模式。
在终端运行curl http://localhost:8080/hello
就看到hello world
添加动态URL
from bottle import route, run
@route('/hello/<custon_url>')
def hello():
return "Hello World! %d " custon_url
run(host='localhost', port=8080, debug=True)
终端输入:
http://localhost:8080/hello/dd
Hello World! dd
给 /hello/自定义一个变量
如何进行POST请求
#/usr/bin/env python
from bottle import route, run,request,debug
@route('/table')
def table():
return '''
<html>
<head>
<body>
<form action="/table" method="post">
Name:<input name="name" type="text" />
Gender:<input name="gender" type="text" />
Age:<input name="age" type="text" />
Weight:<input name="weight" type="text" />
Height:<input name="height" type="text" />
<input value="Table" type="submit" />
</form>
</body>
</html>
'''
@route('/table', method='POST')
def for_table():
name = request.forms.get('name')
gender = request.forms.get('gender')
age = request.forms.get('age')
weight = request.forms.get('weight')
height = request.forms.get('height')
return '<p> Name:%s </p><p> Gender:%s </p><p> Age:%s </p><p> Weight:%s </p><p>Height:%s</p>' %(name, gender, age, weight, height)
run(host='0.0.0.0', port=8080, debug=True)
重点在于@route('/table', method='POST')
当访问table页面时,同时带上post的请求,request.forms.get
获取数据给予HTML读取。
查询搜索变量
@route('/search')
def search():
search = request.query.search
return 'search=%s' % (search)
结果:
search=test
这里是request.query
把URL获取的值,返回到网页中。
template模板使用
简单来说就是把上面的post的例子,里面的HTML代码分离出来,放到一个后缀为tpl的文件里。
建一个table.tpl文件
<html>
<head>
<body>
<form action="/table" method="post">
Name:<input name="name" type="text" />
Gender:<input name="gender" type="text" />
Age:<input name="age" type="text" />
Weight:<input name="weight" type="text" />
Height:<input name="height" type="text" />
<input value="Table" type="submit" />
</form>
</body>
</html>
.py文件的内容
from bottle import route,run
from bottle import template
@route('/table')
def table():
return template('table') #模板的名称
run(host='localhost', port=8080, debug=True)
如何把后端的数据传输给远端
.py文件内容
from bottle import route,run
from bottle import template
@route('/table')
def table():
name = 'cxiaodian'
return template('table', name = name)
run(host='localhost', port=5000, debug=True)
.tpl文件内容
<html>
<body>
<p>姓名: </p>
</body>
</html>
显示结果:
姓名: cxiaodian
在.tpl文件模板中,{{name}} 就是后端传过来的数据,return template('table', name = name) 后端return 过来的name 变量给予前端 name显示,模板中{{}}用来调用后端的数据
网页端如何读取本地数据
思考:
先从本地读取本地日记文件
再把读取的数据传送到网页端
本地需要提供一个能让网页端读取的接口
读取本地日记文件
def read_diary(): txt = open('mydiary.txt', 'r') data = txt.readlines() diary_data = txt.read() txt.close() return diary_data
上面的函数读取本地日记,
diary_data
给予读取的数据定义@route('/diary') def diary(): data = read_diary() return template('table', data = data)
把读取的日记输出给予网页端,
<html>
<body>
<ul>
<li>历史日记 : {{data}}</li>
</ul>
</body>
</html>
读取日记成功
思考:
如何把网页端写入的数据保存服务端,并把历史自己显示出来
添加一个写入函数:
def write_diary(writedata):
write_txt =open('mydiary.txt', 'a+')
write_txt.write('\n' + writedata)
write_txt.close()
.tpl
文件写入html
<html>
<form action="/diary" method="post">
<input name="input_data" type="text" />
<input value="写入" type="submit">
</form>
<ul>
% for line in data:
{{line}}<br>
% end
</html>
开始写的html总是不会换行显示,后面参考了 sunoonlee 同学的html模块,需要添加
才解决了这个问题。
% for line in data:
{{line}}<br>
% end
input_data
的数据传给后端,后端写入到本地mydiar.txt文件,再把read_diary()函数返回到给网页端显示。
@route('/diary', method='POST')
def input_data():
do_data = request.forms.get('input_data')
write_diary(do_data)
return template('table' data=read_diary())
网页端写入日记,并能显示出来。
- 20151111 更新
如何从命令端读取网页端数据?
搜索python get url 找到urllib 能够打开URL读取内容,
看了下例子,稍微修改下url
import urllib
response = urllib.urlopen('http://localhost:50007/diary')
response = response.read()
print response
确实是可以把网页端的数据读取出来,但是会把html代码跟输入框也读取出来。
想到能不能在server端单独给予clien端一个接口?
在server添加了一小段代码
@route('/read')
def read_from_url():
return read_diary()
clien端直接读取http://localhost:50007/read
URL,能读取历史日记
如何从终端写入数据到网页端?
查阅了urllib跟urllib2 的例子中, 调用服务端后台给予网页端写入的接口,进行写入日记。
def write_diary(diary):
data = {}
data['input_data'] = diary
data = urllib.urlencode(data)
urllib.urlopen('http://localhost:50007/diary')
再用1w的作业 while 循环判断。
服务端,跟客户端基本框架完成,20151112
还需要:
- 调用 Jinja2模板
- Bootstrap 框架
- DB数据库
如何调用 Jinja2模板
读了jinja官网的帮助文档,看得不是很懂,琢磨了半天大概jinja2模板能跟bootstrap框架结合,让页面更好看把,搜索下Jinja2 templates and Bottle 按照里面的例子摸索下,大概知道jinja是怎么用,指定一个html文件。
@route('/diary')
@jinja2_view('home.html')
到bottstrap官网下载个模板,对html不是很懂,边查边修改,然后直接套用进去。
关于添加数据库
在python 帮助文档,琢磨半天,还是不太懂,后来直接看了下其他同学的代码, sunoonlee 才大概知道是怎么用,直接按照sunoonle的数据库代码修改,琢磨,测试(是不是很不厚道?),运行成功,也能理解怎么去调用了。
添加了数据库,代码改动很多,之前的clent端的代码需要重新修改。
感想
一步步从网页端读取后端的数据,大概了解,网页端与后端的数据是如何进行对接了,bottle调用jinja2模板,加强模板功能,jinja2直接调用bootstrap,减少开发前端的时间成本,就能起到美化网站,而数据库能更好的协助前后端数据的传输,与管理。
发觉有时看了官网一堆文字,都不知道怎么用,而如果直接拿起例子修改,调试,更容易理解。
反