Django 通过 Q 对象动态构建查询语句

需求

需要构建的 SQL 条件如下:

1
where field1 in (1,2) and field2 not in (1,3) and (field3 like "%test%" or field4 like "%test%")

非动态

如果是非动态其实还是比较好实现的

1
2
where = Q(field1__in=(1,2)) & ~Q(field2__in=(1,3)) & (Q(field3__icontains="test") | Q(field4__icontains="test"))
MyObject.objects.filter(where)

动态实现

1
2
3
4
5
6
7
8
9
10
Q1 = Q()
if request.query_params.get("group_id") is not None:
Q1.add(Q(cid_id__in=[1,2]), Q.AND) # 1,2 is the group_id
Q1.add(~Q(id__in=[1,2]), Q.AND)
Q2 = Q()
if request.query_params.get("name") is not None:
Q2.add(Q(schema__icontains=request.query_params.get("name")), Q.OR)
Q2.add(Q(cid__host__icontains=request.query_params.get("name")), Q.OR)
Q2.add(Q(cid__env__name__icontains=request.query_params.get("name")), Q.OR)
MyObject.objects.filter(Q1 & Q2)

上面实现中 cid 为外键 cid_id 为外键表 id 字段,cid__env__namecid 外键表的外键表 env 的字段 name