一、Restful
django中restful是一種api接口的設計規範,通常定義的路由不會出現“動詞”。
(一)flask中的restful
需要插件:flask-restful
1.安裝插件
pip install flask-restful
2.修改main.py,配置

3.使用
from main import api
from flask_restful import Resource
@api.resource('/API/v1/leave/')
class LeaveApi(Resource):
def get(self):
'''
處理get請求
:return:
'''
data = request.args
return 'get請求 %s'%data
def post(self):
'''
處理post請求
:return:
'''
data = request.form
return 'post請求 %s' % data
def put(self):
'''
處理put請求
:return:
'''
data = request.form
return 'put請求 %s' % data
def delete(self):
'''
處理delete請求
:return:
'''
data = request.form
return 'delete請求 %s' % data
get請求
初步封裝,實作根據id查詢和查詢所有資訊
def get(self):
data = request.args
id = data.get('id')
result_data = {}
if id:
leave = LeaveList.query.get(int(id))
if leave is not None:
result_data = {
'request_id':leave.request_id,
'request_name':leave.request_name,
'request_type':leave.request_type,
'request_start':str(leave.request_start),
'request_end':str(leave.request_end),
'request_description':leave.request_description,
'request_phone':leave.request_phone,
'request_status':leave.request_status,
}
else:
leaves = LeaveList.query.all()
result_data = []
for leave in leaves:
one = {
'request_id': leave.request_id,
'request_name': leave.request_name,
'request_type': leave.request_type,
'request_start': str(leave.request_start),
'request_end': str(leave.request_end),
'request_description': leave.request_description,
'request_phone': leave.request_phone,
'request_status': leave.request_status,
}
result_data.append(one)
return 'get請求 %s'% result_data
封裝公共的傳回結構
def __init__(self):
super().__init__()
self.result = {
'method':'',
'vaesion': 'v1',
'data':'',
}
使用
get請求中代碼備援,繼續封裝
# 定義傳回的資料
def create_data(self,leave):
result_data = {
'request_id': leave.request_id,
'request_name': leave.request_name,
'request_type': leave.request_type,
'request_start': str(leave.request_start),
'request_end': str(leave.request_end),
'request_description': leave.request_description,
'request_phone': leave.request_phone,
'request_status': leave.request_status,
}
return result_data
def get(self):
data = request.args
id = data.get('id')
result_data = {}
if id:
leave = LeaveList.query.get(int(id))
if leave is not None:
result_data = self.create_data(leave)
else:
leaves = LeaveList.query.all()
result_data = []
for leave in leaves:
one = self.create_data(leave)
result_data.append(one)
self.result['method'] = 'get'
self.result['data'] = result_data
return jsonify(self.result)
post請求
def post(self):
data = request.form
leave = LeaveList()
leave.request_id = data.get('request_id')
leave.request_name = data.get('request_name')
leave.request_type = data.get('request_type')
leave.request_start = data.get('request_start')
leave.request_end = data.get('request_end')
leave.request_description = data.get('request_description')
leave.request_phone = data.get('request_phone')
leave.request_status = data.get('request_status')
leave.save()
self.result['method'] = 'post'
self.result['data'] = self.create_data(leave)
return self.result
put請求
def put(self):
'''
可更改部分資料
根據id查詢->對象,修改的是對象中的屬性
'''
data = request.form
id = data.get('id')
leave = LeaveList.query.get(id)
for one in data.keys():
if one != 'id':
if hasattr(leave,one):
setattr(leave,one,data.get(one))
leave.merge()
self.result['method'] = 'put'
self.result['data'] = self.create_data(leave)
return self.result
delete請求
def delete(self):
data = request.form
id = data.get('id')
leave = LeaveList.query.get(id)
leave.delete()
self.result['method'] = 'delete'
self.result['data'] = self.create_data(leave)
return self.result
(二)api接口
- api接口提供資料的支援,将前端html和後端進行分離
- 傳回的資料經常是json
- restful風格的接口,命名通常不出現動詞
- 接口開發的目的:增加資料的可用性
寫web頁面,請求api接口擷取資料,前端web可以使用ajax,vue
前後端分離demo
模闆
{% extends 'base.html' %}
{% block title %}
api_demo
{% endblock %}
{% block label %}
api_demo
{% endblock %}
{% block content %}
<p></p>
{% endblock %}
{% block script %}
<script>
$.ajax({
url:'/API/v1/leave/',
type:'get',
data:'',
success:function (data) {
p = '';
console.log(data['data']);
for(one in data['data']){
p += data['data'][one]['request_type']+'<br>';
}
$('p').html(p)
},
error:function (error) {
console.log(error)
}
})
</script>
{% endblock %}
視圖
# 提供資料
from main import api
from flask_restful import Resource
@api.resource('/API/v1/leave/')
class LeaveApi(Resource):
def __init__(self):
super().__init__()
self.result = {
'method':'',
'vaesion': 'v1',
'data':'',
}
# 定義傳回的資料
def create_data(self,leave):
result_data = {
'request_id': leave.request_id,
'request_name': leave.request_name,
'request_type': leave.request_type,
'request_start': str(leave.request_start),
'request_end': str(leave.request_end),
'request_description': leave.request_description,
'request_phone': leave.request_phone,
'request_status': leave.request_status,
}
return result_data
def get(self):
data = request.args
id = data.get('id')
result_data = {}
if id:
leave = LeaveList.query.get(int(id))
if leave is not None:
result_data = self.create_data(leave)
else:
leaves = LeaveList.query.all()
result_data = []
for leave in leaves:
one = self.create_data(leave)
result_data.append(one)
self.result['method'] = 'get'
self.result['data'] = result_data
return jsonify(self.result)
# 提供頁面
@app.route('/api_demo/')
def api_demo():
return render_template('api_demo.html')
二、flask-migrate
flask-migrate是flask對資料模型的管理插件
1.安裝
pip install flask-migrate
解決了我們修改字段不能同步的問題。
通常不單獨使用,需要結合flask-script插件進行使用。
2.配置
main.py
manage.py
3.使用
python manage.py db init # 初始化
python manage.py db migrate # 生成遷移檔案
python manage.py db upgrade # 更新/送出
三、裝飾器
給flask中的類視圖增加裝飾器
使用method_decorators類屬性,Resource會檢測method_decorators類屬性當中有沒有給下面的方法增加裝飾器。
method_decorators = [func1,func2] 代表将該類中的所有方法都增加裝飾器func1和func2
def func1(func):
def inner():
func()
print('裝飾器1')
return inner
def func2(func):
def inner():
func()
print('裝飾器2')
return inner
class Demo(Resource):
method_decorators = [func1,func2]
def get(self):
return 'get'
api.add_resource(Demo,'/Demo/')
結果:
裝飾器1
裝飾器2
這種方法裝飾的get方法,相當于這個順序
@func2
@func1
def get():
pass
給指定的方法增加指定的裝飾器
class Demo(Resource):
method_decorators = {
'get':[func1,func2],
'post':[func2]
}
def get(self):
return 'get'
def post(self):
return 'post'
api.add_resource(Demo,'/Demo/')