如何解决在flask sqlalchemy get请求中传递空参数作为过滤条件 场景没有什么问题问题
场景
我正在构建一个 GET
API,它应该接受参数、应用过滤器并返回结果。
技术栈: flask-restful(框架)、flask-sqlalchemy(orm)、MysqL(数据库)
假设我的 GET
请求中有四个参数,即 p1,p2,p3,p4
,对应的值为 v1,v2,v3,v4
。任何或所有参数都可以为空值。
示例:此 http://myhost.com/apply-filter?p1=v1&p3=v4
是我们案例的有效请求。
假设数据库表中也存在相同的字段(列)。
模型名称为 Model
没有什么问题
API 应该对所有这些参数应用 and
条件并返回满足这些参数的所有行。我对 Flask 和 sqlalchemy 略知一二,所以一开始我是这样做的:
db.session.query(Model).filter(Model.p1 == v1,Model.p2 == v2,Model.p3 == v3,Model.p4 == v4).all()
工作正常...
问题
现在的问题是,如果用户请求没有一个或多个参数的值,我不知道该怎么办,即如果她/他想要怎么办只根据p1和p3过滤?
我知道我可以使用 if...else
解决这个问题,但是有没有更好的方法?
类似于:
db.session.query(Model).filter(Model.p1 == v1 or all,Model.p2 == v2 or all,Model.p3 == v3 or all,Model.p4 == v4 or all)
请求方式:GET
假设只有一张桌子。
使用 request.args.get('param')
Namaste?
解决方法
方法 1(后端)
您可以用比 if...else
更优雅的方式来完成此操作,但不一定更简单。假设这是您的请求网址:
http://myhost.com/apply-filter?p1=v1&p2=&p3=v3
如您所见,p2 的值为空。您必须首先获得参数/值的字典。
args = request.args #args = {"p1": v1,"p2": None,"p3": v3}
接下来,您需要过滤此字典以删除具有 None 值的项目。
filtered_args = {k: v for k,v in args.items() if v is not None} #filtered_args = {"p1": v1,"p3": v3}
您还必须构建一个可使用的 Sqlalchelmy 过滤器 (BinaryExpression):
filters = [getattr(Model,attribute) == value for attribute,value in filtered_args.items()]
最后,您可以使用 and_ 连词进行查询:
db.session.query(Model).filter(and_(*filters)).all()
方法 2(前端)
您还可以在发出 api 请求之前过滤前端的请求。这可以通过最初不包括具有空值的参数来完成。否则,您将不得不使用一些基本的 Javascript 代码来删除不必要的参数 (Source)
let url = new URL('https://example.com?foo=1&bar=2&foo=3');
let params = new URLSearchParams(url.search);
// Delete the foo parameter.
params.delete('foo'); //Query string is now: 'bar=2'
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。