天天看點

Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

一、Restful

django中restful是一種api接口的設計規範,通常定義的路由不會出現“動詞”。

(一)flask中的restful

需要插件:flask-restful

1.安裝插件

pip install flask-restful
           

2.修改main.py,配置

Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

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':'',
    }
           

使用

Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

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
           
Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

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
           
Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

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
           
Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

(二)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

Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器
Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

manage.py

Flask架構(五)--flask-restful,flask-migrate一、Restful二、flask-migrate三、裝飾器

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/')
           

繼續閱讀