过滤

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