refactor: 外键字段过滤支持 / filter_fields支持配置lookup_prefixes
parent
8394f92178
commit
dbcbf117bb
|
@ -249,16 +249,16 @@ class UserViewSet(CustomModelViewSet):
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
create_serializer_class = UserCreateSerializer
|
create_serializer_class = UserCreateSerializer
|
||||||
update_serializer_class = UserUpdateSerializer
|
update_serializer_class = UserUpdateSerializer
|
||||||
# filter_fields = ["name", "username", "gender", "is_active", "dept", "user_type"]
|
filter_fields = ["^name", "~username", "^mobile", "is_active", "dept", "user_type", "$dept__name"]
|
||||||
filter_fields = {
|
# filter_fields = {
|
||||||
"name": ["icontains"],
|
# "name": ["icontains"],
|
||||||
"mobile": ["icontains"],
|
# "mobile": ["icontains"],
|
||||||
"username": ["icontains"],
|
# "username": ["icontains"],
|
||||||
"gender": ["icontains"],
|
# "gender": ["icontains"],
|
||||||
"is_active": ["icontains"],
|
# "is_active": ["icontains"],
|
||||||
"dept": ["exact"],
|
# "dept": ["exact"],
|
||||||
"user_type": ["exact"],
|
# "user_type": ["exact"],
|
||||||
}
|
# }
|
||||||
search_fields = ["username", "name", "gender", "dept__name", "role__name"]
|
search_fields = ["username", "name", "gender", "dept__name", "role__name"]
|
||||||
# 导出
|
# 导出
|
||||||
export_field_label = {
|
export_field_label = {
|
||||||
|
|
|
@ -150,6 +150,7 @@ class CustomDjangoFilterBackend(DjangoFilterBackend):
|
||||||
"$": "iregex",
|
"$": "iregex",
|
||||||
"~": "icontains",
|
"~": "icontains",
|
||||||
}
|
}
|
||||||
|
filter_fields = "__all__"
|
||||||
|
|
||||||
def construct_search(self, field_name, lookup_expr=None):
|
def construct_search(self, field_name, lookup_expr=None):
|
||||||
lookup = self.lookup_prefixes.get(field_name[0])
|
lookup = self.lookup_prefixes.get(field_name[0])
|
||||||
|
@ -157,19 +158,32 @@ class CustomDjangoFilterBackend(DjangoFilterBackend):
|
||||||
field_name = field_name[1:]
|
field_name = field_name[1:]
|
||||||
else:
|
else:
|
||||||
lookup = lookup_expr
|
lookup = lookup_expr
|
||||||
|
if lookup:
|
||||||
if field_name.endswith(lookup):
|
if field_name.endswith(lookup):
|
||||||
return field_name
|
return field_name
|
||||||
return LOOKUP_SEP.join([field_name, lookup])
|
return LOOKUP_SEP.join([field_name, lookup])
|
||||||
|
return field_name
|
||||||
|
|
||||||
def find_filter_lookups(self, orm_lookups, search_term_key):
|
def find_filter_lookups(self, orm_lookups, search_term_key):
|
||||||
for lookup in orm_lookups:
|
for lookup in orm_lookups:
|
||||||
# if lookup.find(search_term_key) >= 0:
|
# if lookup.find(search_term_key) >= 0:
|
||||||
new_lookup = lookup.split("__")[0]
|
new_lookup = LOOKUP_SEP.join(lookup.split(LOOKUP_SEP)[:-1]) if len(lookup.split(LOOKUP_SEP)) > 1 else lookup
|
||||||
# 修复条件搜索错误 bug
|
# 修复条件搜索错误 bug
|
||||||
if new_lookup == search_term_key:
|
if new_lookup == search_term_key:
|
||||||
return lookup
|
return lookup
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# CASE: 前端query string过滤
|
||||||
|
# def find_filter_lookups(self, orm_lookups, search_term_key):
|
||||||
|
# for lookup, lookup_expr in orm_lookups.items():
|
||||||
|
# # if lookup.find(search_term_key) >= 0:
|
||||||
|
# search_key = self.construct_search(search_term_key, lookup_expr)
|
||||||
|
# new_lookup = LOOKUP_SEP.join(search_key.split(LOOKUP_SEP)[:-1]) if len(search_key.split(LOOKUP_SEP)) > 1 else lookup
|
||||||
|
# # 修复条件搜索错误 bug
|
||||||
|
# if new_lookup == lookup:
|
||||||
|
# return search_key
|
||||||
|
# return None
|
||||||
|
|
||||||
def get_filterset_class(self, view, queryset=None):
|
def get_filterset_class(self, view, queryset=None):
|
||||||
"""
|
"""
|
||||||
Return the `FilterSet` class used to filter the queryset.
|
Return the `FilterSet` class used to filter the queryset.
|
||||||
|
@ -189,7 +203,13 @@ class CustomDjangoFilterBackend(DjangoFilterBackend):
|
||||||
utils.deprecate(
|
utils.deprecate(
|
||||||
"`%s.filter_fields` attribute should be renamed `filterset_fields`." % view.__class__.__name__
|
"`%s.filter_fields` attribute should be renamed `filterset_fields`." % view.__class__.__name__
|
||||||
)
|
)
|
||||||
filterset_fields = getattr(view, "filter_fields", None)
|
self.filter_fields = getattr(view, "filter_fields", None)
|
||||||
|
if isinstance(self.filter_fields, (list, tuple)):
|
||||||
|
filterset_fields = [
|
||||||
|
field[1:] if field[0] in self.lookup_prefixes.keys() else field for field in self.filter_fields
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
filterset_fields = self.filter_fields
|
||||||
|
|
||||||
if filterset_class:
|
if filterset_class:
|
||||||
filterset_model = filterset_class._meta.model
|
filterset_model = filterset_class._meta.model
|
||||||
|
@ -327,14 +347,17 @@ class CustomDjangoFilterBackend(DjangoFilterBackend):
|
||||||
return queryset
|
return queryset
|
||||||
if filterset.__class__.__name__ == "AutoFilterSet":
|
if filterset.__class__.__name__ == "AutoFilterSet":
|
||||||
queryset = filterset.queryset
|
queryset = filterset.queryset
|
||||||
orm_lookups = []
|
# orm_lookups = []
|
||||||
for search_field in filterset.filters:
|
# for search_field in filterset.filters:
|
||||||
if isinstance(filterset.filters[search_field], CharFilter):
|
# if isinstance(filterset.filters[search_field], CharFilter):
|
||||||
orm_lookups.append(
|
# orm_lookups.append(
|
||||||
self.construct_search(six.text_type(search_field), filterset.filters[search_field].lookup_expr)
|
# self.construct_search(six.text_type(search_field), filterset.filters[search_field].lookup_expr)
|
||||||
)
|
# )
|
||||||
else:
|
# else:
|
||||||
orm_lookups.append(search_field)
|
# orm_lookups.append(search_field)
|
||||||
|
orm_lookups = [self.construct_search(str(search_field)) for search_field in self.filter_fields]
|
||||||
|
# CASE: 前端query string过滤
|
||||||
|
# orm_lookups = {lookup: filterset.filters[lookup].lookup_expr for lookup in filterset.filters.keys()}
|
||||||
conditions = []
|
conditions = []
|
||||||
queries = []
|
queries = []
|
||||||
for search_term_key in filterset.data.keys():
|
for search_term_key in filterset.data.keys():
|
||||||
|
|
|
@ -92,6 +92,23 @@ export const crudOptions = (vm) => {
|
||||||
disabled: true
|
disabled: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '部门名称',
|
||||||
|
key: 'dept__name',
|
||||||
|
treeNode: true, // 设置为树形列
|
||||||
|
search: {
|
||||||
|
disabled: false,
|
||||||
|
component: {
|
||||||
|
props: {
|
||||||
|
clearable: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show: false,
|
||||||
|
form: {
|
||||||
|
disabled: true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '账号',
|
title: '账号',
|
||||||
key: 'username',
|
key: 'username',
|
||||||
|
@ -174,7 +191,7 @@ export const crudOptions = (vm) => {
|
||||||
title: '部门',
|
title: '部门',
|
||||||
key: 'dept',
|
key: 'dept',
|
||||||
search: {
|
search: {
|
||||||
disabled: true
|
disabled: false
|
||||||
},
|
},
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
type: 'tree-selector',
|
type: 'tree-selector',
|
||||||
|
|
Loading…
Reference in New Issue