前言
最近在使用 Django
配合 DRF
(django-rest-framework
) 开发 CD
系统调度器,遇到了这个需求。
之前做侧开,主要侧重于测试,也进行过这种列表接口的测试。也熟悉了标准的调用方法。现在主要侧重于开发,就轮到我开发这种接口了。
查了下 DRF
默认支持的查询机制和前端需要的有点不一样。所以在这里把具体实现记录下。
需求
手头上现有一个发布单的列表接口,可以返回目前已经创建的发布单信息,并结合 DRF
已经配置了序列化和分页。
现在需要接口可以支持使用请求参数来过滤返回的发布单列表信息,也就是添加查询参数。并且要支持某个参数的多选查询。
实际请求过来的 url
会在原先的 url
后添加上类似 ?name=first&status=0,1
这样的一串信息。它的意思是:使用 name
和 status
来进行查询,返回 (name
为 first
) 且 (status
为 0
或 1
)
思路
定制查询参数
DRF
中提供了一个组件 SearchFilter
(源码在此)来提供查询功能。该组件可以通过类属性 search_param
指定 url
中的查询关键字,通过类属性 search_fields
指定 查询关键字对应的数据表的字段。一个关键字可以对应多个字段。
SearchFilter
默认的匹配逻辑是:只要数据表中某条记录的某个指定字段满足匹配,就记为当前查询关键字的一条查询结果。
举个例子,假设现在的情况是:
- 查询关键字是
name
, - 查询的值是
first
, - 数据表的匹配逻辑是
icontains
, - 数据表中有三个字段
id
、pre_name
和post_name
,search_fields
设置为关联pre_name
和post_name
。
则最终返回的查询结果是 pre_name
或 post_name
字段的值包含 first
的记录的集合
SearchFilter
查询关键字对应的多个 数据表字段之间采用了 或逻辑。DRF
中的一个 ListCreateAPIView
可以支持设定多个 SearchFilter
,以列表的形式使用。每个 SearchFilter
可以定制对应的 search_param
和 search_fields
,多个 SearchFilter
的结果之间采用 与逻辑
多选查询
难点
SearchFilter
对于多选查询的默认逻辑是 与逻辑。
举个例子,假设现在的情况是:
- 查询关键字是
status
, - 查询的值是
0,1
, - 数据表的匹配逻辑是
iexact
, - 数据表中有三个字段
id
、name
和status
,search_fields
设置为关联status
。
则最终返回的查询结果是 status
字段的值 等于 0
且 等于 1
的记录的集合。
这不是扯淡嘛。需求需要的是返回 status
字段的值 等于 0
或