django中drf怎么在Filter中去掉某个字段的过滤

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. 怎么对前端参数做二次处理;

 


Comments(0) Add Your Comment

Not Comment!