Flask 第十八话之Restful API

一、安装

pip install flask-restful

 二、基本使用

1.导入Api,和Resource,来创建api对象

2.创建视图类

3.使用api.add_resource方法做url映射:

  参数值:视图类,url,别名

注:url中可以携带参数:/login/<username>/ === post请求需要接收参数username

from flask import Flask,render_template,url_for
from flask_restful import Api,Resource

app = Flask(__name__)
api = Api(app)

# http://127.0.0.1:5000/login/aaaa/
class LoginViews(Resource):
    def post(self,username):
        return {'name':('aaa','bbb')}

# 参数:视图类,url,别名
# url中可以携带参数:/login/<username>/  === post请求需要接收参数username
api.add_resource(LoginViews,'/login/<username>/',endpoint = 'login')

with app.test_request_context():
    # 反转url
    print(url_for('login',username='aaa'))
    # 如果没有endpoint值那么就用视图函数的小写
    # print(url_for('indexviews',username='aaa'))


if __name__ == '__main__':
    app.run(debug=True)

三、验证数据合法性

1.需要导入reqparse来进行验证

2.创建验证对象:parse = reqparse.RequestParser()

3.添加验证字段:parse.add_argument('username',type=str,help='用户名验证错误',required =True,default='设置默认值')

add_argument参数说明:

  1.default:默认值
  2.required:是否必须

  3.type:类型

  4.choices:选项,提交上来得值必须符合这个选项中得值才能通过
  5.help:错误信息

  6.trim:是否取出前后空格

  注:type可以使用python自带得一些数据类型,也可以使用flask_restful.inputs下得一些特定得数据类型来强制转换比如
  1.url:判断参数是否是url
  2.regex:正则表达式
  3.date:将字符串转换为datetime.date类型,如果转换失败则抛出异常

示例代码:

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

app = Flask(__name__)
api = Api(app)

class LoginViews(Resource):

    def post(self):
        """
        传入参数:username,password
        :return:
        """
        parse = reqparse.RequestParser()
        """
        add_argument:
        1.default:默认值
        2.required:是否必须
        3.type:类型
        4.choices:选项,提交上来得值必须符合这个选项中得值才能通过
        5.help:错误信息
        6.trim:是否取出前后空格
        
        注:type可以使用python自带得一些数据类型,也可以使用flask_restful.inputs下得一些特定得数据类型来强制转换比如
        1.url:判断参数是否是url
        2.regex:正则表达式
        3.date:将字符串转换为datetime.date类型,如果转换失败则抛出异常
        """
        parse.add_argument('username',type=str,help='用户名验证错误',required =True,default='设置默认值')
        parse.add_argument('password',type=str,help='密码验证错误')
        parse.add_argument('age',type=int,help='年龄不正确')
        parse.add_argument('gender',type=str,choices=['',''],help='密码验证错误')
        parse.add_argument('url',type=inputs.url,help='链接验证错误')
        parse.add_argument('telphone',type=inputs.regex(r'1[8942]d{9}'),help='电话验证错误')
        parse.add_argument('birth',type=inputs.date,help='生日验证错误')
        args = parse.parse_args()

        print(args)
        return {'name':('aaa','bbb')}

api.add_resource(LoginViews,'/login/',endpoint = 'login')


if __name__ == '__main__':
    app.run(debug=True)

 四、返回响应数据

1.定义models模型,用户与文章1对多得关系,文章与标签多对多得关系

from exts import db

# 用户模型 1用户多文章
class User(db.Model):
    __tablename__ = "user"
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    username = db.Column(db.String(50),nullable=False)
    email = db.Column(db.String(50),nullable=False)

# 文章和标签多对多关系,第三张表
article_to_tag = db.Table(
    'article_tag',
    db.Column('article_id',db.Integer,db.ForeignKey('article.id'),primary_key=True),
    db.Column('tag_id',db.Integer,db.ForeignKey('tag.id'),primary_key=True)
)


# 文章模型
class Article(db.Model):
    __tablename__ = "article"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
    # 1对多文章反查用户
    author = db.relationship("User",backref="articles")
    # 多对多文章和标签绑定
    tags = db.relationship("Tag",backref = "Tag",secondary=article_to_tag)

# 标签模型
class Tag(db.Model):
    __tablename__ = "tag"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(50), nullable=False)

2.创建数据,使用article表进行数据创建

from flask import Flask
from flask_restful import Api,Resource,fields,marshal_with
import config
from exts import db
from models import User,Article,Tag
app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)

api = Api(app)

@app.route('/')
def index():
    u = User(username="小啊哈",email = "895025041@qq.com")
    article = Article(title = "温州有事呢",content='aaaaaaaaaaaaaaaaaa')
    article.author = u

    tag1 = Tag(name="前端")
    tag2 = Tag(name="PYTHON")
    tag3 = Tag(name="JAVA")
    article.tags.append(tag1)
    article.tags.append(tag2)
    article.tags.append(tag3)

    db.session.add(article)
    db.session.commit()
    return "首页"

3.定义模型返回数据

class ArticleViews(Resource):
    resource_fields = {
        # 指定参数attribute重命名
        'article_title':fields.String(attribute='title'),
        'content':fields.String,
        'author':fields.Nested({
            "username":fields.String,
            "email":fields.String
        }),
        'tags':fields.List(fields.Nested({
            "id":fields.Integer,
            "name":fields.String
        })),
        # 设置默认值default为null时显示默认值
        'read_count': fields.Integer(default=80),
    }

    @marshal_with(resource_fields)
    def get(self,article_id):
        article = Article.query.get(article_id)
        return article

api.add_resource(ArticleViews,'/article/<article_id>',endpoint='article')

4.返回结果

{
    "article_title": "u6e29u5ddeu6709u4e8bu5462",
    "content": "aaaaaaaaaaaaaaaaaa",
    "author": {
        "username": "u5c0fu554au54c8",
        "email": "895025041@qq.com"
    },
    "tags": [
        {
            "id": 1,
            "name": "u524du7aef"
        },
        {
            "id": 2,
            "name": "PYTHON"
        },
        {
            "id": 3,
            "name": "JAVA"
        }
    ],
    "read_count": 80
}

五、restful与蓝图结合使用

 1.app中注册蓝图

from articleviews import article_bp
app.register_blueprint(article_bp)

2.蓝图文件中

from flask import Blueprint,render_template
from flask_restful import Resource,Api,fields,marshal_with
from exts import db
from models import Article

article_bp = Blueprint("article",__name__,url_prefix='/article')
api = Api(article_bp)

class ArticleViews(Resource):
    resource_fields = {
        # 指定参数attribute重命名
        'article_title':fields.String(attribute='title'),
        'content':fields.String,
        'author':fields.Nested({
            "username":fields.String,
            "email":fields.String
        }),
        'tags':fields.List(fields.Nested({
            "id":fields.Integer,
            "name":fields.String
        })),
        # 设置默认值default为null时显示默认值
        'read_count': fields.Integer(default=80),
    }

    @marshal_with(resource_fields)
    def get(self,article_id):
        article = Article.query.get(article_id)
        return article


api.add_resource(ArticleViews,'/<article_id>',endpoint='article')

六、restful使用模板

注:需要使用representation('text/html') 将restful默认得json返回格式变为html返回格式,创建函数使用make_response将其响应给前端

from flask import Blueprint,render_template,make_response
from flask_restful import Resource,Api,fields,marshal_with
from exts import db
from models import Article

article_bp = Blueprint("article",__name__,url_prefix='/article')
api = Api(article_bp)

@api.representation('text/html')
def out_html(data,code,headers):
    print(data)
    resp = make_response(data)
    return resp

class ListViews(Resource):

    def get(self):

        return render_template('lists.html')

api.add_resource(ListViews,'/list',endpoint='list')
原文地址:https://www.cnblogs.com/lee-xingxing/p/12501831.html