Flask - 高级查询
查询操作
filter
比较
filter中支持 python中的所有比较运算符:==、!=、>、<、>=、<=
from flask_restful import Resource, reqparse, marshal_with
from .models import Goods
from .fields import goods_fields
class GoodsView(Resource):
@marshal_with(goods_fields)
def get(self):
# 1. 客户端传递 参数,
parser = reqparse.RequestParser()
parser.add_argument('sales', type=int, location=['args'], default=0)
sales = parser.parse_args().get('sales')
# 2. 查询销量大于该参数的所有商品
goods = Goods.query.filter(Goods.sales > sales).all()
return goods
注意: 过滤完成之后,还需要调用
all()获取 查询的 结果
逻辑
from flask_restful import Resource, reqparse, marshal_with
from .models import Goods
from .fields import goods_fields
from sqlalchemy import or_, and_, not_
class GoodsView(Resource):
@marshal_with(goods_fields)
def get(self):
# 1. 客户端传递 参数,
parser = reqparse.RequestParser()
parser.add_argument('sales', type=int, location=['args'], default=0)
parser.add_argument('stock', type=int, location=['args'], default=0)
sales = parser.parse_args().get('sales')
stock = parser.parse_args().get('stock')
# 2. 查询销量大于 某个数 或 库存小于 某个数 的商品信息
goods = Goods.query.filter(or_(Goods.sales > sales, Goods.stock < stock)).all()
return goods
from flask_restful import Resource, reqparse, marshal_with
from .models import Goods
from .fields import goods_fields
from sqlalchemy import or_, and_, not_
class GoodsView(Resource):
@marshal_with(goods_fields)
def get(self):
# 1. 客户端传递 参数
parser = reqparse.RequestParser()
parser.add_argument('max_price', type=float, location=['args'])
parser.add_argument('min_price', type=float, location=['args'])
max_price = parser.parse_args().get('max_price')
min_price = parser.parse_args().get('min_price')
if (max_price is None) and (min_price is None):
# 上限 和 下限 都没有
goods = Goods.query.all()
elif (max_price is None) and (min_price is not None):
# 有 下限 ,没有 上限
goods = Goods.query.filter(Goods.price >= min_price).all()
elif (max_price is not None) and (min_price is None):
# 有 上限 ,没有 下限
goods = Goods.query.filter(Goods.price <= max_price).all()
else:
# 查询 价格在某个区间的商品信息
goods = Goods.query.filter(and_(Goods.price >= min_price, Goods.price <= max_price)).all()
return goods
模型类.query.filter(模型类.字段 > 值).all(): 比较查询,支持所有比较运算符模型类.query.filter(or_(条件1, 条件2)).all(): 满足任何一个条件即可模型类.query.filter(and_(条件1, 条件2)).all(): 满足全部条件即可模型类.qery.filter(模型类.字段.in_([1, 2, 3, 4])): 查询某个字段是否 在某个 集合中,用来实现 批量操作
判断
# 查询库存不为空 的商品信息
goods = Goods.query.filter(not_(Goods.stock.is_(None))).all()
goods = Goods.query.filter(~(Goods.stock.is_(None))).all()
# id在某个区间的商品信息
goods = Goods.query.filter(Goods.id.in_([1, 3, 6, 7])).all()
模糊查询
from flask_restful import Resource, reqparse, marshal_with
from .models import Goods
from .fields import goods_fields
class GoodsView(Resource):
@marshal_with(goods_fields)
def get(self):
#
parser = reqparse.RequestParser()
parser.add_argument('text', type=str, location=['args'])
text = parser.parse_args().get('text')
# sql语句中的模糊查询中,
# %: 代表 任意个任意字符
# _: 代表一个任意字符
# 查询商品名包含xxx的商品信息
# goods = Goods.query.filter(Goods.name.like('%{}%'.format(text))).all()
# 查询 以 xx 开头 的商品信息
goods = Goods.query.filter(Goods.name.like('{}%'.format(text))).all()
return goods
排序
from flask_restful import Resource, reqparse, marshal_with
from .models import Goods
from .fields import goods_fields
from sqlalchemy import desc, asc
class GoodsView(Resource):
@marshal_with(goods_fields)
def get(self):
# 接收客户端发送的参数,按照参数进行排序
parser = reqparse.RequestParser()
parser.add_argument('params', type=str, location=['args'])
params = parser.parse_args().get('params')
if params == 'price':
goods = Goods.query.order_by('price').all()
elif params == '-price':
goods = Goods.query.order_by(desc('price')).all()
elif params == 'sales':
goods = Goods.query.order_by('sales').all()
elif params == '-sales':
goods = Goods.query.order_by(desc('sales')).all()
else:
goods = Goods.query.all()
return goods
desc(字段): 按照字段 降序排序
asc(字段): 按照字段升序排序,不写asc也是升序排序
关联关系:一对多
模型类
from app.extensions import db
# 商品: 商品属于分类
# 分类 分类反向查询商品
class Cate(db.Model):
__tablename__ = 'tb_cate'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), unique=True)
class Goods(db.Model):
__tablename__ = 'tb_goods'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), unique=True, nullable=False)
price = db.Column(db.DECIMAL(8, 2), nullable=False)
sales = db.Column(db.Integer, default=0)
stock = db.Column(db.Integer, default=0)
# 表中实际存在 的 外键字段
cate_id = db.Column(db.Integer, db.ForeignKey('tb_cate.id'))
# 字段,表中没有,只是体现 分类和商品的 关联关系, 方便后期的关联查询
cate = db.relationship('Cate', backref='goods')
序列化字段
from flask_restful import fields
goods_fields = {
# 和模型类的字段名一一对应
'id': fields.Integer,
'name': fields.String,
'price': fields.String,
'sales': fields.Integer,
'stock': fields.Integer,
# 'cate_id': fields.Integer, # 直接序列化 外键字段
# 'cate': fields.String, # 前提是 模型类需要分类模型类 重写 __str__ 方法,返回分类的名字
# 'c_name': fields.String(attribute='cate.name'), # 自定义字段。需要指明序列化解析的字段, 注意: cate 就是 模型类中的 关联字段
# 'c_id': fields.Integer(attribute='cate.id'),
# 将商品对应的分类按照 嵌套格式 进行解析
"cate": fields.Nested({
'id': fields.Integer,
'name': fields.String
})
}
视图
商品
from flask_restful import Resource, reqparse, marshal_with
from .models import Goods
from .fields import goods_fields
from app.extensions import db
class GoodsView(Resource):
# 商品添加:外键当做普通的字段即可
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, location=['form', 'json'], required=True, help='输入合法的商品名')
parser.add_argument('price', type=float, location=['form', 'json'], required=True, help='输入合法的商品价格')
parser.add_argument('stock', type=int, location=['form', 'json'], default=0, help='输入合法的库存')
parser.add_argument('sales', type=int, location=['form', 'json'], default=0, help='输入合法的销量')
parser.add_argument('cate_id', type=int, location=['form', 'json'], required=True, help='输入合法的分类id')
args = parser.parse_args()
goods = Goods(**args)
db.session.add(goods)
try:
db.session.commit()
except:
return {'msg': '添加失败'}, 500
return {'msg': '添加成功'}, 201
# 查询所有商品,以及对应的分类信息
@marshal_with(goods_fields)
def get(self):
goods = Goods.query.all()
return goods
分类商品
查询某个分类对应的 商品信息
- 以商品表为主,通过外键进行过滤查询
class GoodsCateView(Resource):
@marshal_with(goods_fields)
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('cate_id', type=int, location='args', required=True, help='需要合适的分类信息')
cate_id = parser.parse_args().get('cate_id')
# 以商品表为主,通过外键进行过滤
goods = Goods.query.filter_by(cate_id=cate_id).all()
return goods
路由
api.add_resource(GoodsCateView, '/goods/cate/')
# http://127.0.0.1:5000/goods/cate/?cate_id=xxx
- 以分类表为主,先查分类对象,再反向查询 对应的商品列表
class CateGoodsView(Resource):
# cate/xx/goods
@marshal_with(goods_fields)
def get(self, pk):
# 先通过id,查询分类对象
cate = Cate.query.get_or_404(pk)
# 通过模型类中的 backref 属性 实现 反向查询
return cate.goods
路由
api.add_resource(CateGoodsView, '/cate/<int:pk>/goods/')
# http://127.0.0.1:5000/cate/xxx/goods/

浙公网安备 33010602011771号