2025-08-29 10:12:44 by wst
django采用drf的好处有很多,今天我们来探讨一下filter的作用。
它可以帮助我们过滤数据,省的判断前端哪个字段传了,哪个没传,以及字段之间的组合。
下面的例子,你觉得会过滤哪些字段呢?
class LedgerReportLogFilter(django_filters.FilterSet):
"""
台账日志过滤器
"""
# orderID = django_filters.CharFilter(field_name='orderID', lookup_expr='icontains')
platformValue = django_filters.CharFilter(field_name='platform_id', lookup_expr='exact')
logIDValue = django_filters.CharFilter(field_name='logID', lookup_expr='exact')
createTime = django_filters.CharFilter(method='filter_create_time')
vul_id = django_filters.CharFilter(method='filter_by_vul_id')
vul_manage_type = django_filters.CharFilter(method='filter_vul_manage_type')
timeStamp = django_filters.CharFilter(method='filter_timestamp')
def filter_create_time(self, queryset, name, value):
"""
根据 createTime 范围过滤
"""
# 解析前端传递的时间戳范围
try:
start_time, end_time = map(int, value.split('-'))
except (ValueError, TypeError):
return queryset.none() # 如果格式不正确,返回空查询集
# 将时间戳转换为 datetime 对象
start_datetime = timestamp_to_datetime(start_time)
end_datetime = timestamp_to_datetime(end_time)
# 应用范围过滤
return queryset.filter(create_datetime__gte=start_datetime, create_datetime__lte=end_datetime)
def filter_by_vul_id(self, queryset, name, value):
# Step 1: 根据 vul_id 查出所有 logID
# 执行 ES 查询
es = get_es_client()
# 构造 ES 查询条件
query = {
"query": {
"bool": {
"must": []
}
}
}
query["query"]["bool"]["must"].append({"match": {"vulInfoID": value}})
# todo: 修改索引名字为vul_info_id_log_id
response = es.search(index=ES_INDEX.vul_info_id_log_id.value, body=query)
# 提取结果
results = response['hits']['hits']
log_ids = [hit['_source']['logID'] for hit in results if '_source' in hit and 'logID' in hit['_source']]
# Step 2: 用这些 logID 过滤 logInfoReqParams
return queryset.filter(logID__in=log_ids)
def filter_vul_manage_type(self, queryset, name, value):
"""过滤漏洞管理类型"""
keys_for_value = lambda v, d=procLedgerMapping: [k for k in d if d[k] == v]
types = keys_for_value(int(value))
return queryset.filter(logType__in=types)
def filter_timestamp(self, queryset, name, value):
"""过滤日志发生时间"""
try:
start_time, end_time = map(int, value.split('-'))
except (ValueError, TypeError):
return queryset.none() # 如果格式不正确,返回空查询集
# 应用范围过滤
return queryset.filter(timeStamp__gte=int(start_time), timeStamp__lte=int(end_time))
class Meta:
model = logInfoReqParams
exclude = ['orderID']
分析如下:
1. createTime字段,前端传递的数据格式为“1753754654-1756433081”,我们把它转成时间范围过滤create_time字段;
2. vul_id字段,需要先用前端传递的值到es中查询logID, 然后再用logID过滤数据;
3. vul_manage_type字段,需要进行一次映射,然后再去过滤数据;
4. timeStamp字段,也是需要先分隔前端的时间,然后再进行过滤;
5. exclude = ['orderID']部分,这里设置orderID不参与过滤;但是如果设成fields = '__all__',即便把orderID字段注释掉,然后会进行orderID的过滤。
总结知识点如下:
1. 怎么设置某个字段不过滤;
2. 怎么对前端参数做二次处理;