Python 学习笔记5
来源:互联网 发布:超级基因优化液扫书 编辑:程序博客网 时间:2024/05/17 22:58
5、Python Web开发
1Web 开发介绍
1-1 Web 开发概述
C/S
B/S – web开发
访问网站的过程:
静态网站
动态网站 – 网站由于用户的请求不同,而呈现出不同的的结果
MVC
M –Model模型,存储web应用数据的代码– user类的实现,对象
V –View视图,格式化和显示web应用的用户界面的代码– 首页,视频
C –Controller控制器,将Web应用粘合在一起并提供业务逻辑的代码– 联系M和V,用于登记,注册
CGI – Common Gateway Interface
可以让一个客户端,从网页浏览器向服务器请求数据。这是描述客户端和服务器程序之间传输数据的一种标准。
1-2 Web 应用的结构
Web应用结构概览:
前端程序 – HTML CSSJS
后台程序 – pythonPHP JSP
数据库 – MySQL MongoDB
前端
HTML– 超文本标记语言
CSS– 层叠样式表
JS– JavaScript
后端- Python PHP JSP ASP/ASP.NET
数据库- MySQL MongoDB SQLite
1-3 HTML 和 JavaScript 的简单介绍
目标:实现两个数的加法
2 用 Python 进行 CGI 编程
2-1 CGI 介绍
CGI
CGI是运行在服务器上的程序,提供同客户端HTML页面的接口。
CommonGateway Interface
CGI程序可以是PythonPerl C C++, 不限定语言
CGI的工作原理
浏览器访问URL并连接到Web服务器
Web服务器接收到请求信息后会解析URL,并查找访问的文件在服务器上是否存在,如果存在就返回文件内容,否则返回错误信息
浏览器从服务器上接收信息,并显示接收的文件或错误信息
其中有一些与数据库交互的工作
缺点与改进
每次CGI请求都会生成一个程序的副本来运行
FastCGI- 先编译
mod_perl– 将解释器作为模块集成在web服务器中
使用c等编译
CGI中环境变量
CONTENT_TYPE:指示传递信息的类型
HTTP_COOKIE:客户机的COOKIE内容
REMOTE_ADDR:发送请求的客户机的IP地址
REQUEST_METHOD:脚本被调用的方法,如GET和POST方法
GET方法
GET方法发送用户信息到服务端,数据信息包含在请求URL上,以?分割
GET请求可被浏览器缓存
GET请求会保存在历史记录中
GET请求有长度的限制
GET请求不应用于敏感场合
GET请求只应当用于取回数据
POST方法
使用POST方法向服务器传递数据是更安全可靠的,像一些敏感数据如用户密码等需要使用POST传输
POST请求包含在HTTP请求的头中
POST请求不会显示在URL中
2-2 python中的web服务器
Python自带的web服务器 – Python自带的包可以建立简单的Web服务器
BaseHTTPServer:提供的基本的web服务和处理类
SimpleHTTPServer: 包含执行GET请求的SimpleHTTPRequestHandler类
CGIHTTPServer: 包含处理POST请求和执行的CGIHTTPRequestHandler类
演示:python –m CGIHTTPServer 8081
使用Apache
第一个CGI程序
创建目录
编写CGI程序
开启服务器
使用浏览器访问
实例:实现简单的GET请求
import cgi,cgitb
form1 = cgi.FieldStorage()
name = form1.getvalue("name")
print "content-type:text/html \n\n"
print "Hello "+name
在命令行中,python –m CGIHTTPServer 8081
在浏览器中,http://localhost:8081/cgi-bin/main.py?name=yx
2-3 实战:用CGI编写加法器
目标:
使用python, GETPOST请求,配合HTML和JS程序,完成之前的加法器。并开启服务器,使得其他人可以访问。
3Python Web 框架开发
3-1 Web 开发框架介绍
框架 – 最基础的软件构架和体系– 骨架
好处:
可重用
成熟,稳健
可扩展性良好
提高开发速度
Web框架
Web应用框架是支持动态网站、网络应用程序的软件框架。
Web框架的工作方式:接受HTTP请求并处理,分派代码,产生HTML,创建HTML响应。
Web框架通常包含了:URL路由,数据库管理,模板引擎。
优点:
着重业务逻辑
高度可重用
选对框架很重要
MVC
ORM – 将具体的类映射为一张表
URL Route – URL不同的地址映射到不同的函数中,来完成不同的操作
修饰器
Temple – 模板引擎 – 将后台的数据通过渲染的方式传递给前端代码
3-2 python中的web框架
常见的web框架:
大包大揽的Django
力求精简的web.py和Tornado
新生代的微框架Flask和Bottle
Django的优点:
完美的文档
全套的解决方案(Cache,Session, ORM……)
强大的URL路由配置
自助管理后台
Django的缺点:
系统紧耦合
自带的ORM不够强大
Template比较弱
微框架的优点:
聚焦在业务逻辑上
学习成本低
灵活性和伸缩性较强
微框架的缺点:
很多逻辑需要开发者操刀
安装很多模块之后体积较大
Flask框架
保持核心简单,易于扩展
不包含数据库抽象层,表单验证等。但可以添加扩展。
Flask是一个可扩展框架
安装Flask框架
在目录C:\Python27\Scripts中,pip install flask
检验:python
Import flask
3-3 使用Flask框架编写加法器
目标:
使用python,Flask框架,配合HTML和JS程序,完成之前的加法器。并开启服务器,使得其他人可以访问
在HTML文件中编写非HTML代码时,需要使用{{ }}
4Flask 表单开发
4-1 表单介绍
表单– html中的数据采集器
含义:可以采集到用户输入的内容
组成:标签、域、按钮
功能:通过表单,将用户输入的数据提交给服务端,并交由服务端进行处理
表单标签– 声明表单的范围,位于表单标签中的元素将被提交
语法:<form></form>
属性:Method –GET POST, Enctype, action…
表单域
语法:<input……/>
属性:type,name,value…
种类:文本框<…type=text>
密码框<…type=password>
文本区域<textarea></textarea>
文件上传框<…type=file>
单选框<…type=radio>
复选框<…type=checkbox>
表单按钮
提交按钮 <inputtype="submit" value="Submit">
复位按钮 reset
一般按钮 button
实例– 一个含有多种元素的表单
使用HTML语言,尝试编写一个含有多种元素的表单。并进行简单的排版,尝试通过JS取得页面元素的值
// index.html
<<!DOCTYPE html>
<html>
<head>
<title></title>
<scripttype="text/javascript" src="getValue.js"></script>
</head>
<body>
<formname="form1">
<inputtype="text" placeholder="Text" name='text1' />
<inputtype="password" placeholder="password"name="password"/>
<textareaplaceholder="Textarea" name="textarea"style="resize:none"></textarea>
<inputtype="file" name="file"/>
<inputtype="radio" name="option"value="option1"/>Option1
<inputtype="radio" name="option"value="option2"/>Option2
<inputtype="checkbox" name="check"value="Option1"/>Option1
<inputtype="checkbox" name="check"value="Option2"/>Option2
<inputtype="submit" value="Submit"/>
<inputtype="reset" value="Reset"/>
<inputtype="button" value="button"onclick="getValue()">
</form>
</body>
</html>
function getValue () {
vartext = document.form1.option.value; //单选框返回的是一个元素
alert(text)
//body...
}
function getValue () {
var arr = document.form1.check; //复选框返回的是一个数组
alert(arr[0].value);
// body...
}
4-2 表单的提交方式
get 和 post
GET方式通过URL提交数据,数据在URL中可以看到的
POST方式,数据放置在HTML Header中提交
例如:GET 方式:https://www.baidu.com/s?wd=yuxiang
POST方式:在HTTP头中提交wd=yuxiang
两者区别:
GET请求可以被浏览器缓存
POST所请求的URL可以被缓存,但数据不会缓存
POST请求不便于分享
POST请求没有长度限制
GET请求的数据暴露在URL中,会带来安全问题
GET方式的适用场合
单纯的请求数据,不进行其他操作
表单数据较短,不超过1024个字符
对安全性要求一般的场合
POST方式的适用场合
数据不仅仅用于请求,例如,需要将数据插入数据库內
表单数据过长,如,博客
要传的数据不是ASCII编码
4-3 实战:用Flask开发用户管理(一)
目标:使用Flask框架,配合HTML和JS程序,编写一个页面,判断用户提交的用户名和密码是否分别为yx和35,如果是则调整到极客学院的首页,否则返回错误信息
//使用request.form从表单中拿用户输入的数据
username= request.form[‘username’]
password = request.form[‘password’]
//给用户提示输入登录信息错误
//index.html
{% if message %} {{ message }} {% endif %}
在模板引擎中,用{%…%}来控制流
//当数据量较大时,使用Flask-wtf构建表单
pip install Flask-wtf
# 在视图函数中得到表单的内容
myForm.username.data== "yx" and myForm.password.data == "35" andmyForm.validate()
代码一:
#main.py
# coding=utf-8
from flask import Flask, request,render_template, redirect, url_for
from wtforms importForm,TextField,PasswordField,validators
class LoginForm(Form):
username= TextField('username',[validators.Required()])#[validators.Required()]表示username必须填入
password= PasswordField('password',[validators.Required()])
app=Flask(__name__)
@app.route('/',methods = ['GET','POST'])
def index():
returnredirect(url_for("login"))
@app.route("/user",methods=['GET','POST'])
def login():
myForm= LoginForm(request.form)
ifrequest.method=='POST':
ifmyForm.username.data == "yx" and myForm.password.data =="35" and myForm.validate(): # 在视图函数中得到表单的内容
returnredirect('http://www.jikexueyuan.com')
else:
message = "LoginFailed"
returnrender_template('index.html',msg=message,fm=myForm) # msg给用户提示输入登录信息错误,fm创建表单
returnrender_template('index.html',fm=myForm)
if __name__ == "__main__":
app.run(port=8080)
代码二:
#index.html
<body>
<divalign="center">
<h1>UserManmgement</h1>
<formmethod="POST">
{%if msg %} {{ msg }} {% endif %} //错误提示信息位置
<br/>
Username:{{fm.username}}//创建用户名表单
<br/>
Password:{{fm.password}}//创建密码输入表单
<br/>
<inputtype="submit" value="Submit"/>
<inputtype="reset" value="reset"/>
</form>
</div>
</body>
5Python 的数据库连接
5-1 数据库基础
数据库
数据库管理系统
数据库分类
关系型数据库:MySQL SQLite PostgreSQL Oracle Access…
非关系型数据库:BigTableMongoDB LevelDB …
为什么使用DBMS?
减少记录编档的时间
减少记录检索的时间
灵活的查找序列
灵活的输出格式
多个用户同时访问记录
安装MySQL数据库和相关管理工具
MySQL
WorkBench – 图形化管理界面
5-2 数据库查询语句SQL
SQL
实例
insert into student (id,name) values(1,'yx') ;
delete from student where id = 2;
update student set name="yuxiang"where id=1;
select * from student where id = 1;
select * from student order by id desc; //降序
select * from student order by id asc; //升序
5-3 在python中进行SQL操作
目标:
1)编写一个Python程序,重复第二课时中数据库操作
2)编写一个Python程序,允许用户输入的内容存储在数据库中
找到C:\Program Files\MySQL\MySQL Server 5.7\bin
在命令行窗口输入:mysql.exe -u root -p,回车后输入mysql的密码,即可进入mysql中
pip install mysql-python
python
import MySQLdb
注:在ubuntu中,建议用apt-get安装
sudo apt-get install python-mysqldb
在Workbench中,勾上表的Auto Increment,表明这个字段是自增的
#! coding=utf-8
import MySQLdb
#connect to db
conn = MySQLdb.connect("localhost","root","root","test")
#create cursor
cur = conn.cursor()
name = raw_input()
#sql
sql = "select * from student"
insert_sql = "insert into student(name) values ('%s')" %(name)
#execute
cur.execute(insert_sql)
conn.commit()#防止数据不一致
cur.execute(sql)
#get the result
result = cur.fetchall()
for row in result:
print row[0]
print row[1]
conn.close()
5-4 实战:使用Flask框架编写用户管理(二)
目标:
使用Flask框架,配合HTML和JavaScript程序,编写两个页面。第一个页面允许用户填入用户名和密码进行注册,第二个页面用户使用刚才的用户名和密码进行登录。
代码:
# db.py
# execute datebase operation
import MySQLdb
conn=MySQLdb.connect("localhost","root","root","test")
cur = conn.cursor()
def addUser(username,password): #向数据库中插入用户名和密码,用户注册
sql= "insert into user (username,password) values ('%s','%s')" %(username,password)
cur.execute(sql)
conn.commit()
conn.close()
def isExisted(username,password): #查询数据,用户登录
sql= "select * from user where username = '%s' and password = '%s'"%(username,password)
cur.execute(sql)
result= cur.fetchall()
if(len(result) == 0):
returnFalse
else:
returnTrue
6 数据库进阶-对象关系映射(ORM)的使用
6-1 对象关系映射 (ORM) 介绍
ORM – 用于实现面向对象程序设计里的不同类型之间系统的数据之间的转换
不同类型之间系统– 面向对象程序(软件工程)和关系型数据库(数据理论)之间数据
为什么要使用ORM
避免和复杂的SQL语句打交道
提高开发效率,也更容易理解
方便形成统一风格的代码
带来一些安全性上的提升
ORM缺点:
系统消耗较大
处理较复杂的查询条件时,使用ORM不够灵活
占用内存较大
Flask中的ORM
Flask-SQLAlchemy:基于SQLAlchemy的Flask扩展
peewee,pyORM
6-2 实战:使用ORM编写用户管理模块(三)
目标
1) 安装配置Flask-SQLAlchemy
2) 在之前用户管理模块的基础上,为用户建立数据模型,通过此模型完成用户的登录、注册等操作
安装:
pip install flask-sqlalchemy
验证:
python
from flask.ext.sqlalchemy import SQLAlchemy
代码一:
#model.py
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] ='mysql://root:root@localhost/test'
db = SQLAlchemy(app)
class User(db.Model): //创建表
id= db.Column(db.Integer,primary_key=True)
username= db.Column(db.String(32),unique=True)
password= db.Column(db.String(32))
def__init__(self,username,password):
self.username= username
self.password= password
在命令行中测试:
进入python
>>>frommodel import *
>>>db
>>> db.create_all() //创建表
到workbench中查找user表
代码二:
defadd(self): //数据库插入,用户注册
try:
db.session.add(self)
db.session.commit()
returnself.id
exceptException,e:
db.session.rollback()
returne
finally:
return0
代码三:
//数据库查询,用户登录
defisExisted(self):
temUser= User.query.filter_by(username=self.username,password=self.password).first()
iftemUser is None:
return0
else:
return1
6-3 实战:使用ORM编写留言板(一)
目标
1) 使用Flask框架以及Flask-SQLAlchemy扩展,建立留言的模型,并通过此模型,完成一个允许用户留言的程序
2) 用户可以输入用户名以及留言内容,发布留言。并将所有用户的留言显示在一个页面中
代码一:
#model.py
class Entry(db.Model):
id= db.Column(db.Integer,primary_key=True)
content= db.Column(db.Text)
sender= db.Column(db.String(32))
def__init__(self,content,sender):
self.content= content
self.sender= sender
defadd(self): #数据库插入,用户将留言板的数据插入
try:
db.session.add(self)
db.session.commit()
returnself.id
exceptException,e:
db.session.rollback()
returne
finally:
return0
def getAllEntry(): #ORM查询操作,简化,从数据库中拿出用户输入的内容
Entlist= []
Entlist= Entry.query.filter_by().all()
returnEntlist
#main.py中调用
e =Entry(myEntryForm.content.data,myEntryForm.sender.data)
e.add()
#main.py中调用
l = getAllEntry()
代码二:
class PublishForm(Form): // 从表单中拿出用户输入的数据
content= TextField('content',[validators.Required()])
sender= TextField('sender',[validators.Required()])
<body>
<formmethod="post">
content:{{fm.content}} //创建表单,用户从此处输入数据
</br></br>
sender: {{fm.sender}}
<input type="Submit"value="Submit"> Submit
<br>
<input type="reset"value="Reset"> Reset
</form>
<ul>
{%for e in entries %}
<li>{{e.content }} Send by {{ e.sender}} //在留言板中输入数据库中的内容
{%endfor %}
</ul>
</body>
7 数据库中的关系
7-1 数据库中的关系概览
关系型数据库就是建立在关系模型基础上的数据库,借助于集合代数等数学上的概念和方法来处理数据库中的数据。
关系模块中的常用的操作有数据查询(如选择,投影,连接,并,交等)和数据操作(增删改查)
表示以行和列组织起来的数据的集合。一个数据库包括一个或多个表。在关系型数据库中,
一个表就是一个关系,一个关系数据库可以包括多个表。
关系的种类:一对一,一对多,多对多
7-2 关系的设计
主键:
数据表中某一记录有若干条属性,若某一属性可以唯一标识一条记录,该属性就可以成为一个主键。
外键:
是用于与另一张表的关联,是能确定另一张表记录的字段,用于保持数据的一致性。
主键要能够被外键有效的引用。
演示:数据表的设计
目标:使用SQL语句和MySQL WorkBench,完成一个可以在数据库中找到特定用户文章的小程序。
一对一:
表region
id
name
team_id
1
beijing
2
2
shenzhen
3
3
guangzhou
1
表team
id
name
1
No.1
2
No.2
select region.*, team.* from region,teamwhere region.team_id = team.id;
id
name
team_id
id
name
3
guangzhou
1
1
no.1
1
beijing
2
2
no.2
2
shenzhen
3
3
no.3
一对多:
表teacher
id
name
1
lisi
2
zhanshan
表course
Id
name
teacher_id
1
python
1
2
web
1
3
java
1
4
c++
2
select teacher.*,course.* fromteacher,course where teacher.id=course.teacher_id;
id
name
id
name
teacher_id
1
lisi
1
python
1
1
lisi
2
web
1
1
lisi
3
java
1
2
zhanshan
4
c++
2
多对多:
表student
id
name
1
zhanshan
2
lisi
3
wangwu
表course
Id
name
teacher_id
1
python
1
2
web
1
3
java
1
4
c++
2
表screlation
id
sid
cid
1
1
1
2
1
2
3
2
1
4
3
1
5
3
3
selectstudent.name,course.name,screlation.* from student,course,screlation wherescrelation.sid=student.id and screlation.cid=course.id;
name
name
id
sid
cid
zhanshan
python
1
1
1
Zhanshan
Web
2
1
2
Lisi
Python
3
2
1
Wangwu
Python
4
3
1
wangwu
java
5
3
3
总结:
一对一和一对多关系,可以在原有的数据表中增加字段来实现
多对多关系,通过新建一张表来实现这样的关系
7-3 实战:留言板(二)
目标:
使用Flask框架以及Flask-SQLAlchemy扩展,将用户的留言板和用户信息进行连接,使其他用户可以看到某一用户的所有留言。
代码:
# model.py 一对多关系
class Item(db.Model):
id= db.Column(db.Integer,primary_key=True)
content= db.Column(db.String(32))
sender_id= db.Column(db.Integer)
def__init__(self,content,sender_id): #创建表
self.content= content
self.sender_id= sender_id
defadd(self): #数据库插入
try:
db.session.add(self)
db.session.commit()
returnself.id
exceptException,e:
db.session.rollback()
returne
finally:
return0
演示:
C:\Users\Administrator\work\PythonSpace\PythonWeb\MessageBoard02>python
Python 2.7.11 (v2.7.11:6d1b6a68f775,Dec 5 2015, 20:32:19) [MSC v.1500 32 bit(
Intel)] on win32
Type "help","copyright", "credits" or "license" for moreinformation.
>>> from model import db
>>> db.create_all()
>>> from model import User,Item
>>> u=User("yx01","012")
>>> u.add()
0
>>>a=User.query.filter_by(username="yx01").first()
>>> a
<model.User object at 0x030E5A50>
>>> a.id
9L
>>> i=Item("12345",9)
>>> i.add()
0
>>> i=Item("3456",9)
>>> i.add()
0
>>> list=[]
>>>list=Item.query.filter_by(sender_id=a.id).all()
>>> list
[<model.Item object at 0x03090ED0>,<model.Item object at 0x03090FF0>]
>>> for e in list:
... print e.content
...
12345
3456
>>>
# main.py
@app.route("/search",methods=['GET','POST'])
def search():
ifrequest.method=='POST':
un=request.form['username']
u=User.query.filter_by(username=un).first()
l=[]
l=Item.query.filter_by(sender_id=u.id).all()
returnrender_template("search.html",content=l)
returnrender_template("search.html")
//search.html
<<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<divalign="center">
<h1>MessageBoard</h1>
{%for message in content %} {{message.content}}<br/>{% endfor %}
<formmethod="POST">
<inputtype="text" name="username" placeholder="Input theusername you want to search">
<br/>
<inputtype="submit" value="Submit"/>
<inputtype="reset" value="reset"/>
</form>
</div>
</body>
</html>
# model.py 多对多关系
class UIRelation(db.Model):
id=db.Column(db.Integer,primary_key=True)
uid=db.Column(db.Integer)
iid=db.Column(db.Integer)
总结:
关系
如何设计简单的关系
使用SQL语句处理关系
使用Flask-SQLAlchemy扩展处理关系
8 发布 Web 应用及补充知识
8-1 将 Web 应用发布到服务器
Web应用的工作流程:
客户端请求Web服务器,服务器返回结果
对服务器(硬件)的要求:
网络访问
可见的IP
一定的存储空间和处理能力
选择云计算:
稳定性更佳
弹性和扩展性
安全
成本低廉
演示:以阿里云为例部署Web应用
目录:将上一节课所写的web应用部署到阿里云服务器上,如条件允许,可以分别在Windows操作系统和Linux操作系统上完成。
部署云服务器:
1)https://www.aliyun.com/
管理控制台 -> 云服务器ECS ->选择地区的云服务器-> 创建实例
2)ssh远程到云服务器
3)Yummy FTP上传文件 SFTP(22)
4)使用vim修改 app.run(host=’0.0.0.0’,port=8080)来监听所有的端口
部署云数据库:
https://www.aliyun.com/
管理控制台-> 云数据库RDS
8-2 Web 应用的模块化——蓝图
模块化– 分割,连接
Flask中的模块化方案 – 蓝图
通过蓝图,一个大型应用可以实例化一个应用对象,初始化几个拓展,并注册几个蓝图。
通过蓝图提供模板过滤器、静态文件等功能。一个蓝图不一定要实现应用或者视图函数。
可以通过URL前缀和/或者子域名来注册一个蓝图。
演示:用户和文章的拆分
目标:使用Flask中Blueprint(蓝图),将用户模块和文章模块进行分离。通过不同的URL来进行区分。
如www.*.com.user/1访问用户的信息,而www.*.com/article/1访问1号文章的信息。
代码:
# user.py
from flask import Blueprint
from model import User
user=Blueprint('user',__name__)
@user.route('/<int:userid>')
def showUser(userid):
u=User.query.filter_by(id=userid).first()
returnu.getUsername()
# model.py
class User(db.Model):
……
defgetUsername(self):
returnself.username
# main.py
app.register_blueprint(user,url_prefix='/user')
8-3 RESTful API 的设计
REST = Representational State Transfer
每个URL代表一种资源
客户端和服务端传递这种资源的表现层
客户端通过四个HTTP动词来进行状态转化
通常传递XML或JSON格式的文本
四个HTTP动词
GET(SELECT):从服务器取出资源(一项或多项)
POST(CREATE):在服务器新建一个资源
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)
DELETE(DELETE):从服务器删除资源
演示:设计简单的RESTful API
目标:使用Flask-Rest插件完成一个简单的RESTful API。返回JSON格式的文本。并进行测试。
安装:pip install flask-restful
检验:
>python
>>>from flask.ext import restful
代码:
# userAPI.py
#coding:utf-8
from flask.ext.restful import reqparse,Resource
from JsonObject import JsonObject
from model import User
auth=reqparse.RequestParser()
class Authentication(Resource):
defget(self):
pass
defpost(self):
auth.add_argument('username',required=True,help="Usernameis Required")
auth.add_argument('password',required=True,help="Passwordis Required")
args=auth.parse_args()
username= args['username']
password= args['password']
u= User(username,password)
jsobj= JsonObject()
ifu.isExisted():
jsobj.put("code",1)
jsobj.put("desc","UserExisted")
else:
jsobj.put("code",2)
jsobj.put("desc","UserNot Existed")
returnjsobj.getJson(),200
#jsonObject.py
import json
class JsonObject():
def __init__(self):
self.dic={}
def put(self,key,value):
self.dic[key]=value
def get(self,key):
return self.dic[key]
def getJson(self):
return json.dumps(self.dic,ensure_ascii=False).replace('}"','}')
def getDic(self):
return self.dic
# userAPI.py
#coding:utf-8
from flask.ext.restful import reqparse,Resource
from JsonObject import JsonObject
from model import User
auth=reqparse.RequestParser()
class Authentication(Resource):
defget(self):
pass
defpost(self):
auth.add_argument('username',required=True,help="Usernameis Required")
auth.add_argument('password',required=True,help="Passwordis Required")
args=auth.parse_args()
username= args['username']
password= args['password']
u= User(username,password)
jsobj= JsonObject()
ifu.isExisted():
jsobj.put("code",1)
jsobj.put("desc","UserExisted")
else:
jsobj.put("code",2)
jsobj.put("desc","UserNot Existed")
returnjsobj.getJson(),200
#server.py
#coding:utf-8
from flask import Flask
from flask.ext.restful import Api
from userAPI import *
app = Flask(__name__)
api = Api(app)
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
api.add_resource(Authentication,'/auth')
if __name__=='__main__':
app.run(port=8080)
在windows中,使用AdvancedRest Client进行四个HTTP动词的测试
8-4 数据库的修改和迁移
数据库的修改:
修正数据库的需求
保持数据的完整性
尽可能减少服务中断时间
Alembic、Flask-Migrate等插件
演示:修改数据库
目标:使用一些第三方插件增加、删除数据库中的字段。
>pip install flask-migrate
>python
>>>from flask.ext import migrate
C:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate>python migrater.py
db init //初始化步骤,建立仓库,在migrations目录中建立一堆文件
C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py:800:UserWarning: SQL
ALCHEMY_TRACK_MODIFICATIONS addssignificant overhead and will be disabled by de
fault in the future. Set it to True to suppress this warning.
warnings.warn('SQLALCHEMY_TRACK_MODIFICATIONS adds significant overheadand wi
ll be disabled by default in thefuture. Set it to True to suppress thiswarnin
g.')
Creating directoryC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\
migrations ... done
Creating directoryC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\
migrations\versions ... done
GeneratingC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\migratio
ns\alembic.ini ... done
GeneratingC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\migratio
ns\env.py ... done
Generating C:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\migratio
ns\env.pyc ... done
GeneratingC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\migratio
ns\README ... done
GeneratingC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\migratio
ns\script.py.mako ... done
Please editconfiguration/connection/logging settings in 'C:\\Users\\Administrat
or\\work\\PythonSpace\\PythonWeb\\4DBMigrate\\migrations\\alembic.ini'before pr
oceeding.
C:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate>python migrater.py
db migrate //对数据库进行检测
C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py:800:UserWarning: SQL
ALCHEMY_TRACK_MODIFICATIONS addssignificant overhead and will be disabled by de
fault in the future. Set it to True to suppress this warning.
warnings.warn('SQLALCHEMY_TRACK_MODIFICATIONS adds significant overheadand wi
ll be disabled by default in thefuture. Set it to True to suppress thiswarnin
g.')
C:\Python27\lib\site-packages\sqlalchemy\engine\default.py:450:Warning: Incorre
ct string value:'\xD6\xD0\xB9\xFA\xB1\xEA...' for column 'VARIABLE_VALUE' at ro
w 475
cursor.execute(statement, parameters)
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'ui_relation'
INFO [alembic.autogenerate.compare] Detected removed table u'ipdata'
INFO [alembic.autogenerate.compare] Detected removed table u'student'
INFO [alembic.autogenerate.compare] Detected removed table u'entry'
INFO [alembic.autogenerate.compare] Detected added column 'item.context'
INFO [alembic.autogenerate.compare] Detected removed column 'item.content'
INFO [alembic.autogenerate.compare] Detected added column 'user.age'
INFO [alembic.autogenerate.compare] Detected added column 'user.male'
GeneratingC:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate\migratio
ns\versions\5d134dc231a4_.py ... done
C:\Users\Administrator\work\PythonSpace\PythonWeb\4DBMigrate>python migrater.py
db upgrade //修改表字段,而这一操作不会损坏表结构,对数据库的升级非常有帮助
C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py:800:UserWarning: SQL
ALCHEMY_TRACK_MODIFICATIONS addssignificant overhead and will be disabled by de
fault in the future. Set it to True to suppress this warning.
warnings.warn('SQLALCHEMY_TRACK_MODIFICATIONS adds significant overheadand wi
ll be disabled by default in thefuture. Set it to True to suppress thiswarnin
g.')
C:\Python27\lib\site-packages\sqlalchemy\engine\default.py:450:Warning: Incorre
ct string value:'\xD6\xD0\xB9\xFA\xB1\xEA...' for column 'VARIABLE_VALUE' at ro
w 475
cursor.execute(statement, parameters)
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 5d134dc231a4, empty messag
e
代码:
#migrater.py
from model import db
from model import app
from flask.ext.script import Manager
from flask.ext.migrate import Migrate,MigrateCommand
migrate = Migrate(app,db)
manager = Manager(app)
manager.add_command('db',MigrateCommand)
if __name__ == '__main__':
manager.run()
#model.py
#coding:utf-8
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] ='mysql://root:root@localhost/test'
db = SQLAlchemy(app)
class User(db.Model):
id= db.Column(db.Integer,primary_key=True)
username= db.Column(db.String(32),unique=True)
password= db.Column(db.String(32))
male= db.Column(db.String(2))
age= db.Column(db.Integer)
def__init__(self,username,password):
self.username= username
self.password= password
defadd(self):
try:
db.session.add(self)
db.session.commit()
returnself.id
exceptException,e:
db.session.rollback()
returne
finally:
return0
defisExisted(self):
temUser=User.query.filter_by(username=self.username,password=self.password).first()
iftemUser is None:
returnFalse
else:
returnTrue
defgetUsername(self):
returnself.username
class Item(db.Model):
id=db.Column(db.Integer,primary_key=True)
context=db.Column(db.String(128))
sender_id=db.Column(db.Integer)
def__init__(self,context,sender_id):
self.context=context
self.sender_id=sender_id
defadd(self):
try:
db.session.add(self)
db.session.commit()
returnself.id
exceptException,e:
db.session.rollback()
returne
finally:
return0
class UIRelation(db.Model):
id=db.Column(db.Integer,primary_key=True)
uid=db.Column(db.Integer)
iid=db.Column(db.Integer)
课程总结:
将应用部署在服务器上
将应用程序模块化
构建RESTful API
使用Flask-Migrate处理数据库升级
- Python学习笔记(5)
- python学习笔记5
- python学习笔记5
- Python 学习笔记 - 5
- Python 学习笔记 5
- python 学习笔记5
- Python学习笔记5
- python 学习笔记5
- Python 学习笔记(5)
- Python学习笔记5
- Python 学习笔记5
- python学习笔记5
- Python学习笔记--5
- python 学习笔记5
- Python学习笔记 5
- python 学习笔记5------序列
- Python学习笔记(5)Timer
- python学习笔记5--decimal
- 搬瓦工shadowsocks多用户配置教程
- solr整合springmvc开发(二)
- linux预习(四)
- 深入理解AbstractQueuedSynchronizer(一)
- 元素全排列递归实现(C++)
- Python 学习笔记5
- 支持多服务器多端口的ShadowSocks客户端
- 搭建shadowsocks服务端部署
- Python 学习笔记6
- 如何实施异构服务器的负载均衡及过载保护?
- Python 学习笔记7
- 继承中构造函数和析构函数的调用顺序
- Python 学习笔记8
- 初认识springMVC错误修改之hibernate_sequence