-
Notifications
You must be signed in to change notification settings - Fork 0
/
filters.py
125 lines (112 loc) · 3.51 KB
/
filters.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""
@Author:WangYuXiang
@E-mile:[email protected]
@CreateTime:2021/3/10 17:25
@DependencyLibrary:无
@MainFunction:无
@FileDoc:
filters.py
文件说明
@ChangeHistory:
datetime action why
example:
2021/3/10 17:25 change 'Fix bug'
"""
LOOKUP_SEP = '__'
from tortoise.models import Q
class ORMAndFilter:
"""以And进行查询
该类将直接得到 ORM_Filter
"""
lookup_prefixes = {
'^': 'istartswith',
'$': 'iendswith',
'>': 'gt',
'<': 'lt',
'>=': 'gte',
'<=': 'lte',
'=': 'contains',
'@': 'icontains'
}
def __init__(self, request, view):
"""
:param request: 当前请求
:param view: 当前视图
"""
self.view = view
self.request = request
def get_search_fields(self):
"""
搜索字段是从视图获取的,但请求始终是
传递给此方法。子类可以重写此方法以
根据请求内容动态更改搜索字段。
"""
return getattr(self.view, 'search_fields', None)
@property
def orm_filter(self):
"""
根据定义的搜索字段过滤传入的queryset
:return: Q object
"""
orm_filters = []
search_fields = self.get_search_fields()
if not search_fields:
return Q(*orm_filters)
for search_field in search_fields:
orm_filters.append(Q(**self.construct_orm_filter(search_field)))
return Q(*orm_filters)
def dismantle_search_field(self, search_field):
"""
拆解带有特殊字符的搜索字段
:param search_field: 搜索字段
:return: (field_name, lookup_suffix)
"""
lookup_suffix_keys = list(self.lookup_prefixes.keys())
lookup_suffix = None
field_name = search_field
for lookup_suffix_key in lookup_suffix_keys:
if lookup_suffix_key in search_field:
lookup_suffix = self.lookup_prefixes[lookup_suffix_key]
field_name = search_field[len(lookup_suffix_key):]
return field_name, lookup_suffix
return field_name, lookup_suffix
def construct_orm_filter(self, search_field):
"""
构造适用于orm的过滤参数
:param search_field: 搜索字段
:return:
"""
field_name, lookup_suffix = self.dismantle_search_field(search_field)
args = self.request.args
if field_name not in args:
return {}
if lookup_suffix:
orm_lookup = LOOKUP_SEP.join([field_name, lookup_suffix])
else:
orm_lookup = field_name
return {orm_lookup: self.get_filter_value(field_name)}
def get_filter_value(self, field_name):
"""
根据字段名从请求中得到值
:param field_name: 字段名
:return:
"""
values = self.request.args.get(field_name)
return ''.join(values)
class ORMOrFilter(ORMAndFilter):
"""以And进行查询
该类将直接得到 ORM_Filter
"""
@property
def orm_filter(self):
"""
根据定义的搜索字段过滤传入的queryset
:return: Q object
"""
orm_filters = []
search_fields = self.get_search_fields()
if not search_fields:
return orm_filters
for search_field in search_fields:
orm_filters.append(Q(**self.construct_orm_filter(search_field)))
return Q(*orm_filters, join_type=Q.OR)