基本操作
目录
创建模型类models
from app.extensions import db
class Books(db.Model):
__tablename__ = 'tb_books'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(20))
read = db.Column(db.Integer)
stock = db.Column(db.Integer)
常用字段:
序列化 (fields)
为什么要进行序列化(将数据库取出的对象转化为JSON格式)
在Flask中,我们常常会选择采用RESTful设计风格,即在各个资源对应的GET、POST、PUT方法中,返回一个JSON格式的数据(资源)给前端使用。这就要求我们在(如get)方法中return一个dict,flask-restful会自动帮我们返回为一个JSON格式的数据。
而通过flask-SQLAlchemy这一ORM工具所构建的数据库表模型,通过其语句所取出的数据通常是object类型的,这一类型并不能直接在方法中return返回一个JSON格式,因此需要先对从数据库中取出的数据进行序列化,然后再return给前端。
from flask_restful import fields
# # 需要和 视图最后的返回结果 相匹配
book_page_fields = {
# goods 对应的商品,是一个 列表包含对象的结构,不能直接解析,使用嵌套关系解析
'books': fields.Nested({
'id': fields.Integer,
'title': fields.String,
'read': fields.Integer,
'stock': fields.Integer
}),
# 分页
'pages': fields.Integer, # 总页码
'total': fields.Integer # 数据总量
}
添加、查看数据(分页)
视图处理过程中,都是接收请求,处理逻辑,返回响应
flask中request
对象 不是 局部对象,也不属于某个视图函数,而是在全局中 拥有同一个 请求对象
将 查询和添加 放到同一个视图中,判断不同的请求方式,从而执行不同的处理逻辑
from flask_restful import Resource, reqparse, marshal_with
from .models import Book
from app.extensions import db
from .fields import book_page_fields
class BookView(Resource):
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('title', type=str, location=['form', 'json'], required=True, help='图书标题不能缺少')
parser.add_argument('bread', type=int, location=['form', 'json'], default=0, help='输入合法的阅读量')
# 1. 获取参数
title = parser.parse_args().get('title')
bread = parser.parse_args().get('bread')
# 2. 创建图书对象
book = Book(title=title, bread=bread)
# 3. 添加图书对象到事务
db.session.add(book)
# 5. 提交事务
try:
db.session.commit()
except:
return {'msg': '添加失败'}, 500
# 6. 正常返回
return {
'id': book.id,
'title': book.title,
'bread': book.bread
}, 201
@marshal_with(book_page_fields)
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('page', type=int, location=['args'], default=1, help='输入合法的页码')
page = parser.parse_args().get('page')
# 1. 先利用模型类查询,并分页, 得到分页器对象
pagination = Book.query.paginate(page=page, per_page=2)
# 2. 返回响应
return {
'books': pagination.items,
'pages': pagination.pages,
'total': pagination.total
}
详情、删除、修改
都是根据ID来查找对应数据,使用三者方法可以写在一个类中
class BookDetailView(Resource):
def get(self, pk):
# 1. 通过主键id,查询 图书对象, id对应的数据不存在,得到结果为None
book = Book.query.get(pk)
# 2. 如果book图书不存在
if not book:
return {
'msg': '图书不存在'
}, 404
# 3. 返回对象
return {
'id': book.id,
'title': book.title,
'bread': book.bread
}
def delete(self, pk):
Book.query.filter_by(id=pk).delete()
db.session.commit()
return None, 204
def put(self, pk):
parser = reqparse.RequestParser()
# 1. 根据主键,查询到需要修改的 图书对象
book = Book.query.get(pk)
# 2. 判断该图书 是否 存在
if not book:
return {
'msg': '找不到'
}, 404
# 3. 解析参数,如果没有传递参数,设置 图书的 原属性 为默认值
parser.add_argument('title', type=str, location=['json', 'form'], default=book.title)
parser.add_argument('bread', type=int, location=['json', 'form'], default=book.bread)
# 4. 获取参数,得到字典
args = parser.parse_args()
# 5.将对象的值,赋值为 传递的新值
book.title = args.get('title')
book.bread = args.get('bread')
# 6.修改完成,需要提交事务,让修改生效
db.session.commit()
return {
'msg': '修改成功'
}, 201
路由配置
book/__init__
from flask_restful import Api
from .views import *
from .models import *
api = Api(books_bp)
api.add_resource(BookView,'/book/')
api.add_resource(BookDetailView,'/book/<int:pk>/')