flask-restful

本文详细讲解了如何在Flask框架中通过Flask-RESTful扩展创建RESTfulAPI,涉及安装、资源定义、HTTP方法、JSON格式数据处理及reqparse工具的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

restful

restful风格是对于传输风格的规范化,更加整齐干净。

安装

首先我们需要安装flask-restful

pip3 install flask-restful

在这里插入图片描述

注册

在ext文件夹中声明api

restful_api=Api()

将flask的app放入到api的.init方法中进行实例化

app=Flask(__name__)
restful_api.init_app(app)

使用

之前我们使用flask本身的blueprint蓝图进行细致分化,引用了flask-restful后,使用的就是定义类方法。

class SpiderResource(Resource):
    def get(self):
        res = requests.get(
            'https://proxy.pixivel.moe/c/540x540_70/img-master/img/2023/02/20/00/15/59/105538757_p0_master1200.jpg')
        dirs = 'C:\\Users\\Administrator\\Desktop\\物体'
        response = make_response(res.content)
        response.headers['Content-Type']='image/jpg'
        return send_file(io.BytesIO(res.content),'image/jpg')

    def post(self):
        pass

我们每次新声明resource都需要注册起来,后面写上你的访问路径

resource_api.add_resouces(SpiderResource,'/spider')

json格式

当我们想要使用application/json格式传输一个自定义对象,他会无法进行dump,所以我们在原本的flask中使用了新声明的方式。
我们在model类中创建一个定义方法

   def blog_dict(self):
       return {
           'id': self.id,
           'user_id': self.user_id,
           'title': self.title,
           'description': self.description,
           'content': self.content,
           'create_time': self.create_time.strftime("%Y-%m-%d"),
           'status': self.status,
           'gallery': self.gallery,
           'comment_amount': Comment.query.filter(Comment.b_id == self.id).count(),
           'type':self.type.t_name
       }
       

然后利用python的simple expression将blogs里的每一个取出来使用自己的方法,然后再次保存。

blogs = Blog.query.filter(Blog.user_id == 1).all()
jsonify(blogs=[e.blog_dict() for e in blogs],

那在restful中,我们可以使用它的方法进行实现,首先我们创建一个自定义对象的dict

blog_fields={
            'id': fields.Integer,
            'user_id': fields.Integer,
            'title': fields.String,
            'description': fields.String,
            'content':fields.String,
            'create_time': fields.DateTime('%Y-%m-%d'),
            'status': fields.Integer,
            'gallery': fields.String,
            # 'comment_amount': Comment.query.filter(Comment.b_id == self.id).count(),
            # 'type':self.type.t_name
        }

然后在你要传输的方法上写上注解marshal_with(dict)

class HomeResource(Resource):
      @marshal_with(blog_fields)
    def get(self, limit):
        uid = session.get('uid')
        count = 0
        pageUtil = PageUtil(limit, 2)
        if uid is not None:

这样就可以传输json值了。

路径传参

https:/localhost:8080/user/1这个意思就是访问id为1的用户,那我们如何这样访问呢。

class UserSimpleApi(Resource):
def get(self):
   pass

restful_api.add_resource(UserSimpleApi,'/user/<int:id>',endpoint='get_user')

在这里插入图片描述

大家可以看到,更改的地方就是在本身设置url的地方增加一个参数,就可以了。

add_resource还有一个endpoint的参数,跟flask的一样,填上后,用来改变url rule。

reqparse

flask-restful为我们提供了attribute的检查,我们可以使用。

创建一个parse对象

parse=reqparse.RequestParser(bundle)

利用这个parse对象添加argument

parse.add_arrgument('username',type=str)
parse.add_arrgument('password',type=str,required=True,help='必须输入密码')

add_argument

1.type:规定传参类型
2.required=bool :规定必须拥有
3.help:如果拥有required后,他没有填写可以用help进行提示
4.location:必须是post请求
5.action:将参数规定为

剩下具体的可以看源码

获取所有值使用

args=parse..parse_args()
user=args.get('username')
password=args.get('password')

对于判断里面有required的,没有填就会返回错误,统一封装到叫message的json数据里返回。

{
message{
'username':'error  username'
}
}

bundle_erros

但是他只会爆出来第一个错误,那如何让他把错误都显示出来呢,就需要在声明parse的时候参数里面加上bundle_errors=True

parser = reqparse.RequestParser(bundle_errors=True)

自定义fields

必须继承 raw
必须实现format函数

class IsDelete(fields.Raw):
    def format(self, value):
        pass
# 这里使用attribute将forms内容传入自定义fields
user_fields={
'id':fields.string,
'is_delete':IsDelete(attribute=isDelete)
}

复杂数据输出

上面我们只是演示了普通数据的传输,假如我们对象里面还有一个新的对象,或者一个新的对象列表,那他是无法进行遍历的,这个时候我们应该怎么办,这里有两个方法。

fields.Nested(fiedls)

使用fields.Nested(field)可以完成一对一的操作。在方法体上面你要写上注解**@marshal_with(fleds)**

user_fields = {
    'id': fields.Integer,
}
type_fields={
    't_id':fields.Integer,
}
blog_fields = {
    'type':fields.Nested(type_fields),
    'writer':fields.Nested(user_fields)
}

一对多的写法:

在外面加上fields.List()

comment_fields={
    'id': fields.Integer,
    'u_id': fields.Integer,
    'b_id': fields.Integer,
    'comment': fields.String,
    'write_time': fields.DateTime(),
}
# 意思是将他转换为comment_fields类型的列表
blog_fields = {
    'id': fields.Integer,
    'comments':fields.List(fields.Nested(comment_fields))
}

marshal()

这是一种不使用装饰器的区别,你不需要再写注解,但是你的数据段里面需要加上marshal自己更改。
第一个参数是你的自定义类,第二个参数是你要转换的fields。

blog_fields = {
    'id': fields.Integer,
    'user_id': fields.Integer,
    'title': fields.String,
    'description': fields.String,
    'content': fields.String,
    'create_time': fields.DateTime('iso8601'),
    'status': fields.Integer,
    'gallery': fields.String,
    'comment_amount': fields.String,
    'url': fields.Url(endpoint='simple_blog', absolute=True),
    'type':fields.Nested(type_fields),
    'writer':fields.Nested(user_fields)
}

def get(self){
        data = {
            'blogs': marshal(blogs, blog_fields)
        }
        return data;
}

这些就是restful的正常使用了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值