过滤¶
Flask-REST-JSONAPI有非常灵活的过滤系统。过滤系统的操作,完全由ResourceList管理器的数据层提供的接口来实现。这里,我们将介绍SQLAlchemy数据层的过滤接口,同样,我们也可以实现定制的数据层过滤接口。过滤功能的使用,我只需要在url中添加“filter”查询参数即可。当然,语句也必须符合JSONAPI 1.0的规范。
注:
为了可读性,以下例子未进行url编码。
SQLAlchemy¶
SQLAlchemy数据层的过滤系统接口与Flask-Restless提供的完全一样。以下为第一个例子:
GET /persons?filter=[{"name":"name","op":"eq","val":"John"}] HTTP/1.1
Accept: application/vnd.api+json
在这个例子中,我们过滤得到了名为John的人。我们发现,过滤接口其实就是SQLalchemy原生提供的方法:列表+过滤信息。
- name: 我们想要过滤的字段名
- op: 操作符(这要SQLAlchemy提供,就可以使用)
- val: 我们想要比较的值。我们也可以在此用“field”替换,即另一个字段,来进行比较。
GET /persons?filter=[{"name":"name","op":"eq","field":"birth_date"}] HTTP/1.1
Accept: application/vnd.api+json
在上面的例子中,我们想要过滤人名和生日一样的人。虽然例子比较搞笑,但我们只是为了解释下这种用法。
如果,我们想要过滤关系型数据,我们可以:
GET /persons?filter=[
{
"name": "computers",
"op": "any",
"val": {
"name": "serial",
"op": "ilike",
"val": "%Amstrad%"
}
}
] HTTP/1.1
Accept: application/vnd.api+json
注:
当我们过滤关系时,使用“any”操作符来过滤“对多”关系;使用“has”操作符来过滤“对一”关系。
另外,我们也能使用一种快捷的方式实现同样的功能:
GET /persons?filter=[{"name":"computers__serial","op":"ilike","val":"%Amstrad%"}] HTTP/1.1
Accept: application/vnd.api+json
我们也能用“与或非”来联结操作:
GET /persons?filter=[
{
"name":"computers__serial",
"op":"ilike",
"val":"%Amstrad%"
},
{
"or": {
[
{
"not": {
"name": "name",
"op": "eq",
"val":"John"
}
},
{
"and": [
{
"name": "name",
"op": "like",
"val": "%Jim%"
},
{
"name": "birth_date",
"op": "gt",
"val": "1990-01-01"
}
]
}
]
}
}
] HTTP/1.1
Accept: application/vnd.api+json
常用操作符:
- any: 过滤对多关系
- between: 过滤一个字段位于两个值之间
- endswith: 检查是否以某个字符串结尾
- eq: 等于
- ge: 大于或等于
- gt: 大于
- has: 过滤对一关系
- ilike: 检查是否包含某个字符串(大小写不明感)
- in_: 检查是否包含在list中
- is_: 检查字段是否是某个值
- isnot: 检查字段是否不是某个值
- like: 检查是否包含某个字符串
- le: 小于或等于
- lt: 小于
- match: 匹配
- ne: 不等于
- notilike: 检查是否不包含某个字符串(大小写不明感)
- notin_: 检查是否不包含在list中
- notlike: 检查是否不包含某个字符串
- startswith: 检查是否以某个字符串开始
注:
使用常用操作符时,要看model的字段类型是否支持该操作。
简单过滤¶
简单过滤仅支持“eq”操作符。每个简单过滤语句,都会转换成其默认的过滤语句,并添加到过滤列表的末尾。
例:
GET /persons?filter[name]=John HTTP/1.1
Accept: application/vnd.api+json
等同于:
GET /persons?filter[name]=[{"name":"name","op":"eq","val":"John"}] HTTP/1.1
Accept: application/vnd.api+json
同样,我们也能在请求中,使用多个简单过滤:
GET /persons?filter[name]=John&filter[gender]=male HTTP/1.1
Accept: application/vnd.api+json
等同于:
GET /persons?filter[name]=[{"name":"name","op":"eq","val":"John"}, {"name":"gender","op":"eq","val":"male"}] HTTP/1.1