【Flask框架】—— 30 Flask-RESTful

news2024/11/25 10:39:21

在这里插入图片描述

在这里插入图片描述


前后端分离和前后端不分离

前后端不分离
在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高

这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口。
前后端分离
在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。

在前后端分离的应用模式中 ,前端与后端的耦合度相对较低。

在前后端分离的应用模式中,我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。

一、RESTful定义

RESTful是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTful适用于移动互联网厂商作为业务使能接口的场景。

在这里插入图片描述

RESTFUL特点包括:
1、每一个URI代表1种资源;

2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;

3、通过操作资源的表现形式来操作资源;

4、资源的表现形式是XML或者 JSON

5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。

二、RESTful风格的软件架构

RESTful架构是对MVC架构改进后所形成的一种架构,通过使用事先定义好的接口与不同的服务联系起来。在RESTful架构中,客户端使用POSTDELETEPUTGET四种请求方式分别对指定的URL资源进行增删改查操作。因此,RESTful是通过URI实现对资源的管理及访问,具有扩展性强、结构清晰的特点。

RESTful架构将服务器分成前端服务器和后端服务器两部分,前端服务器为用户提供无模型的视图;后端服务器为前端服务器提供接口。浏览器向前端服务器请求视图,通过视图中包含的AJAX函数发起接口请求获取模型。

项目开发引入RESTful架构,利于团队并行开发。在RESTful架构中,将多数HTTP请求转移到前端服务器上,降低服务器的负荷,使视图获取后端模型失败也能呈现。但RESTful架构却不适用于所有的项目,当项目比较小时无需使用RESTful架构,项目变得更加复杂。

三、安装和使用

1.安装

pip install flask-restful

在这里插入图片描述

2.普通使用

from flask import Flask
from flask_restful import Api, Resource

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    def get(self):
        return {'get': 'get'}

    def put(self):
        return {'put': 'put'}

    def post(self):
        return {'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

2.蓝图使用

# -*- coding: utf-8 -*-
from flask import Flask, Blueprint
from flask_restful import Api, Resource

bp = Blueprint('user', __name__)
app = Flask(__name__)

# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(bp)


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    def get(self):
        return {'get': 'get'}

    def put(self):
        return {'put': 'put'}

    def post(self):
        return {'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')

# 注册蓝图
app.register_blueprint(bp, url_prefix='/user')
# 注意:当前情况下api的接口访问地址 = 蓝图的url_prefix + 资源请求的路径


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

注意:如果蓝图里面有url_prefix,那么请求url = url_prefix + resource_url

四、Request和RequestParser类

1、RequestParser类

Flask-RESTful 提供了 RequestParser 类,用来帮助我们检验和转换请求数据。

from flask_restful import reqparse

def post(self):
    # 1.创建请求参数校验的对象requestParser
    rq = reqparse.RequestParser()

    # 2.定义参数的校验申明
    rq.add_argument('a', required=True, location='args')

    # 3.启动校验
    req = rq.parse_args()
    # 4.校验完后得到参数的值
    a = req.a
    return {'post': 'post', "a": a}

在这里插入图片描述

使用步骤:

  1. 创建请求参数校验 RequestParser 对象。
  2. RequestParser 对象中添加需要检验或转换的参数声明。
  3. 使用 parse_args() 方法启动检验处理。
  4. 检验之后从检验结果中获取参数时可按照字典操作或对象属性操作。

2、参数说明

1、required

描述请求是否一定要携带对应参数,默认值为False

  • True 强制要求携带
    若未携带,则校验失败,向客户端返回错误信息,状态码400

  • False 不强制要求携带
    若不强制携带,在客户端请求未携带参数时,取出值为None

2、help
参数检验错误时返回的错误描述信息

3、action
描述对于请求参数中出现多个同名参数时的处理方式
action='store' 保留出现的第一个, 默认
action='append' 以列表追加保存所有同名参数的值

4、choices

rq.add_argument('c', type=str, choices=['男', '女'], action='append', location='args')

5、type
描述参数应该匹配的类型,可以使用python的标准数据类型string、int,也可使用Flask-RESTful提供的检验方法,还可以自己定义。
标准类型

rq.add_argument('b', type=str, required=True, action='append', location='args')

Flask-RESTful提供
检验类型方法在 flask_restful.inputs 模块中

  • url
  • regex(指定正则表达式)
  • natural 自然数0、1、2、3…
  • positive 正整数 1、2、3…
  • int_range(low ,high) 整数范围
  • boolean 布尔类型

6、location
描述参数应该在请求数据中出现的位置

# Look only in the POST body 表单
parser.add_argument('name', type=int, location='form')

# Look only in the querystring 请求地址?后面的参数
parser.add_argument('PageSize', type=int, location='args')

# From the request headers  请求头
parser.add_argument('User-Agent', location='headers')

# From http cookies
parser.add_argument('session_id', location='cookies')

# From json
parser.add_argument('user_id', location='json')

# From file uploads  文件提交
parser.add_argument('picture', location='files')

也可指明多个位置,中括号 [ ]

parser.add_argument('text', location=['headers', 'json'])
# -*- coding: utf-8 -*-

from flask import Flask
from flask_restful import Api, Resource, reqparse, inputs

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    def get(self):
        return {'get': 'get'}

    def put(self):
        return {'put': 'put'}

    def post(self):
        # 1.创建请求参数校验的对象requestParser
        rq = reqparse.RequestParser()

        # 2.定义参数的校验申明
        rq.add_argument('a', type=int, required=True, help='参数a错误', location='args')
        # 如果定义help,那么所有的校验只有一种
        rq.add_argument('b', type=str, required=True, action='append', location='args')
        rq.add_argument('c', type=str, choices=['男', '女'], action='append', location='args')
        rq.add_argument('d', type=inputs.regex('^\d{2}$'), location='args')  # 只允许两位整数
        rq.add_argument('e', type=inputs.int_range(1, 100), location='args')  # 允许范围内
        rq.add_argument('f', type=inputs.boolean)  # 只允布尔类型
        # 3.启动校验
        req = rq.parse_args()
        # 4.校验完后得到参数的值
        a = req.a
        b = req.b
        c = req.c
        d = req.d
        return {"a": a, 'b': b, 'c': c, 'd': d}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')


# app.run可以省略
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

在这里插入图片描述


五、RESTful的响应处理

1、序列化数据

Flask-RESTful 提供了marshal工具,用来帮助我们将数据序列化为特定格式的字典数据,以便作为视图的返回值。

from flask import Flask
from flask_restful import Api, Resource, fields, marshal, marshal_with

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


class User(object):
    def __init__(self, username, passwd, user_id):
        self.uname = username
        self.pwd = passwd
        self.id = user_id


# 为了把模型对象转换为字典,在marshal里面必须定义一个属性转换格式
property_fields = {
    'pwd': fields.String,
    'uname': fields.String
}


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    @marshal_with(fields=property_fields, envelope='user01')
    def get(self):  # 获取
        u = User('zhang san', '123123', 1)
        return u

    def put(self):  # 更新
        return {'put': 'put'}

    def post(self):  # 新建资源
        return {'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')


# app.run可以省略
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

也可以不使用装饰器

class HelloResource(Resource):

    # @marshal_with(fields=property_fields, envelope='user01')
    def get(self, **kwargs):  # 获取
        u = User('zhang san', '123123', 1)
        return marshal(u, property_fields, envelope='user01')

2、定制返回的JSON格式

需求: 想要接口返回的JSON数据具有如下统一的格式

{"message": "描述信息", "data": {要返回的具体数据}}

在接口处理正常的情况下, message返回ok即可,但是若想每个接口正确返回时省略message字段

u = User('zhang san', '123123', 1)

对于诸如此类的接口,能否在某处统一格式化成上述需求格式?

{
    "message": "OK",
    "data": {
        "pwd": "123123",
        "uname": "zhang san"
    }
}

解决
Flask_RESTful的Api对象提供了一个representation的装饰器,允许定制返回数据的呈现格式

@api.representation('application/json')
def output_json(data, code, headers=None):
    """Makes a Flask response with a JSON encoded body"""

    # 此处添加自己定义的json格式规则
    if 'message' not in data:
        data = {'message': 'OK',
                'data': data}

Flask-RESTful原始对于json的格式处理方式如下:
在这里插入图片描述

from flask import Flask
from flask_restful import Api, Resource, fields, marshal, marshal_with

from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps

app = Flask(__name__)
# 需求,对外提供一个API接口,可以访问某个资源
# 步骤一:创建restful的API
api = Api(app)


class User(object):
    def __init__(self, username, passwd, user_id):
        self.uname = username
        self.pwd = passwd
        self.id = user_id


# 为了把模型对象转换为字典,在marshal里面必须定义一个属性转换格式
property_fields = {
    'pwd': fields.String,
    'uname': fields.String
}


@api.representation('application/json')
def output_json(data, code, headers=None):
    """Makes a Flask response with a JSON encoded body"""

    # 此处添加自己定义的json格式规则
    if 'message' not in data:
        data = {'message': 'OK',
                'data': data}

    settings = current_app.config.get('RESTFUL_JSON', {})

    # If we're in debug mode, and the indent is not set, we set it to a
    # reasonable value here.  Note that this won't override any existing value
    # that was set.  We also set the "sort_keys" value.
    if current_app.debug:
        settings.setdefault('indent', 4)
        settings.setdefault('sort_keys', not PY3)

    # always end the json dumps with a new line
    # see https://github.com/mitsuhiko/flask/pull/1262
    dumped = dumps(data, **settings) + "\n"

    resp = make_response(dumped, code)
    resp.headers.extend(headers or {})
    return resp


# 步骤二,定义资源resource
class HelloResource(Resource):

    # 定义各种操作(函数)
    # @marshal_with(fields=property_fields, envelope='user01')
    def get(self, **kwargs):  # 获取
        u = User('zhang san', '123123', 1)
        return marshal(u, property_fields)

    def put(self):  # 更新
        return {'put': 'put'}

    def post(self):  # 新建资源
        return {'post': 'post'}


# 步骤三:把资源加载到Api中才能对外发布
api.add_resource(HelloResource, '/hello')


# app.run可以省略
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/154259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iclr 2022 Compositional attention: Disentangling search and retrieval

Mittal S, Raparthy S C, Rish I, et al. Compositional attention: Disentangling search and retrieval[J]. arXiv preprint arXiv:2110.09419, 2021. 目录Mittal S, Raparthy S C, Rish I, et al. Compositional attention: Disentangling search and retrieval[J]. arXiv p…

【Kettle报错】kettle7.0链接MySQL显示:No appropriate protocol

【Kettle7.0链接本地MySQL数据库报错】 1. 问题描述 报错问题:kettle7.0报错,提示No appropriate protocol (protocol is disabled or cipher suites are inappropriate) 错误原因: Caused by: javax.net.ssl.SSLHandshakeException: No a…

Vue实现路由(Vue-router,参数传递,编程式路由导航)

目录 路由是什么? 怎么实现路由 第一步 创建一个文件夹 router ,里面创建一个index.js 内容是 第二步 在main.js中引入和应用 router 第三步 在Vue中 通过两个标签进行配置 跳转路由时的参数传递 query params query参数和 param参数的区别 编…

原型链和JSON

对象的封装、继承和多态 封装、继承和多态是面向对象编程的三大特征,在JavaScript中也可以使用这些特征来实现面向对象的的编程。 封装是指将对象的属性和方法封装在对象内部,只提供必要的接口给外部访问。封装可以让我们隐藏对象的实现细节,…

项目管理:制定项目进度计划的好处有哪些?

项目管理计划确定了项目执行、监控及结束项目的整个过程,在项目开始之前,如能制定清晰的计划,并让项目成员都了解项目的目标和自己的责任,会对项目的推进有很大的帮助。 制定项目进度计划的好处有哪些? 1、目标导向…

高级树结构之二叉查找树

文章目录一 二叉查找树简介二 创建和插入操作三 查找操作3.1 查找思路3.2 代码实现四 删除操作4.1 情况讨论4.2 代码实现五 完整代码5.1 二叉查找树的结构5.2 完整代码内容一 二叉查找树简介 二叉查找树【二叉搜索树或是二叉排序树】 左子树中所有结点的值,均小于其…

(十一)devops持续集成开发——jenkins流水线发布一个docker harbor仓库版的前端vue项目

前言 本节内容,我们使用jenkins的流水线功能发布一个docker harbor私服仓库版的前端vue项目,延续前一节的内容,这里需要我们事先安装好一个docker harbor仓库用来存放我们项目的镜像,前端项目依然是通过nginx基础镜像构建&#x…

关于时间复杂度什么是时间复杂度

文章目录简介常见的Big-Oh简介 精确的考虑程序运行时间会使得寸步难行,而且毫无意义,所以可以用一种“概量”的概念来衡量运行时间,称之为“时间复杂度”。 时间复杂度的定义: 在一个完全立项状态下的计算机中,我们定…

【Sql Server】数据库的表变量和临时表的区别,并通过变量表随机生成姓名

作者:小5聊 简介:一只喜欢全栈方向的程序员,欢迎咨询,尽绵薄之力答疑解惑 公众号:有趣小馆,一个有趣的关键词回复互动功能 效果 1、表变量 1.1、表变量基本信息 1)表变量本质是一个变量 是SQ…

《啊哈算法》第一章典例+解析+代码

目录 一,计数排序 二,冒泡排序(Bubble Sort) 三,快速排序(Quick Sort) 四,桶排序(Bucket Sort) 五,小哼买书 从无到有掌握最基础的算法 多学…

react hooks 封装一个countDown 倒计时组件

开发技术 react , hooks , ts , taro 需求分析 需要一个可以按天,时,分和秒来进行倒计时的组件。 简单使用 注:主要逻辑请看 useCountDown import CountDown from /components/countDown; import { useEffect, useState } from react; i…

东宝商城项目(二)——flask-script模块、flask-migrate模块和项目日志配置

学习flask-script模块的使用 1、什么是flask-script flask-script是flask的一个扩展模块,Flask-Script的作用是可以通过命令行的形式来操作Flask。 2、安装flask-script pip install flask-script 3、flask-script的使用 例如有这样一种需求: 我们…

李彦宏开年定调“百度式创新”:反馈驱动,坚定技术

今天在百度热搜看到这么一条置顶话题,让我印象深刻:读懂中国经济的信心所在。 站在2023年起点,无论你是阳了、没阳,还是阳康了,之于个人、企业组织,都太需要信心和激励了。 点进去后是一篇来自《人民日报 …

小程序直播加速抢占电商流量先机

临近春节,到了购置年货的时候,相信有不少小伙伴被淘宝、拼多多、抖音等各大平台的直播卖货吸引。近年来,大家逐渐发现视频直播的影响力已经渗透到各行各业,通过直播带来的流量,不少商家赚得盆满钵满。视频直播这块流量…

Autosar MCAL-GPT配置及使用

文章目录前言GPTGptChannelConfigSetGptChannelIdGptChannelModeGptChannelTickFrequencyGptChannelTickValueMaxGptEnableWakeupGptNotificationGptChannelClkSrcRefGptAssignedHwUnitGptConfigurationOfOptApiServicesGptDeinitApiGptEnableDisableNotificationApiGptTimeEla…

系列33 Flow_Model

Introduction 在上一小节中讲到了Latent Variable Model(LAM),VAE。其主要思想就是将隐变量扩充为高维连续的分布,来增强模型的表达能力。而LAM模型中的核心困难是计算不出来,因为,而的维度过高算不出来。而…

GAN Step By Step -- Step7 WGAN

GAN Step By Step 心血来潮 GSBS,顾名思义,我希望我自己能够一步一步的学习GAN。GAN 又名 生成对抗网络,是最近几年很热门的一种无监督算法,他能生成出非常逼真的照片,图像甚至视频。GAN是一个图像的全新的领域&#…

2022 OceanBase 年度报告|用技术让海量数据的管理和使用更简单!

尊敬的各位客户、合作伙伴和开发者: 从 2020 年 6 月 1 日 OceanBase 开启商业化至今,我们一起走过了 900 多天。 从 0.5 到 3.x,我们花了近十年时间,而从 3.x 到 4.x 只用了不到两年,这是 OceanBase 和客户、伙伴、…

C++ 开发环境其实挺难搞的(上)

所谓工欲善其事,必先利其器,我将用两节课的内容向大家介绍 C 的开发工具及开发环境的一些知识。 Visual Studio 诞生至今已有 25 年以上的历史,功能强大,用的人非常多,社区的朋友戏称它为宇宙最强大的 IDE&#xff0c…

LeetCode 147. 对链表进行插入排序

🌈🌈😄😄 欢迎来到茶色岛独家岛屿,本期将为大家揭晓LeetCode 147. 对链表进行插入排序,做好准备了么,那么开始吧。 🌲🌲🐴🐴 一、题目名称 二、…