You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django REST Framework中实现QuerySet多参数动态过滤?

解决DRF中多条件过滤时忽略空参数的问题

这个问题我做DRF项目时也碰到过,核心原因是你直接把所有查询参数都传入filter()了——当参数是None或者空字符串时,相当于告诉ORM要找字段值等于None/空字符串的用户,而不是忽略这个过滤条件,这就是为什么没传参数时会返回空列表。

给你一个简洁且扩展性强的解决方案:动态构建过滤条件字典,只保留有有效值的参数,再传入filter()。

修改后的get_queryset代码

class UserListAPIView(ListAPIView):
    """ return the user list """
    pagination_class = UserPageNumberPagination
    # View里不需要Meta类,直接用ordering属性指定排序
    ordering = ['-id']
    
    def get_serializer_class(self):
        return UserListSerializer
    
    def get_queryset(self):
        # 固定过滤条件:排除管理员、staff、超级用户
        filter_conditions = {
            'is_admin': False,
            'is_staff': False,
            'is_superuser': False
        }
        
        # 需要处理的查询参数列表(和模型字段名一致)
        search_params = ['username', 'real_name', 'phone', 'company_name']
        
        # 遍历参数,只保留非空的有效参数
        for param in search_params:
            param_value = self.request.query_params.get(param)
            # 过滤掉None、空字符串,以及纯空格的情况
            if param_value and param_value.strip():
                filter_conditions[param] = param_value
        
        # 如果需要模糊匹配(比如包含关键词),可以把键改成带__contains的形式:
        # filter_conditions[f"{param}__contains"] = param_value
        
        # 用展开字典的方式传入filter
        return User.objects.filter(**filter_conditions)

代码说明

  1. 固定条件与动态条件分离:把is_admin=False这类固定过滤条件先放进字典,再动态添加用户传入的有效参数,逻辑清晰易维护。
  2. 动态构建过滤字典:通过遍历参数列表,只将非空的参数加入过滤条件,避免了写一堆重复if判断的繁琐。
  3. 扩展性强:后续要加新的过滤参数,只需要在search_params列表里新增字段名即可,不用修改核心逻辑。
  4. 排序优化:DRF的ListAPIView支持直接设置ordering属性指定排序规则,之前的Meta类在View里是无效的。

额外优化(可选)

如果后续需要支持模糊查询、范围查询等更复杂的过滤逻辑,可以结合django-filter库,它能更优雅地处理多条件过滤场景,不过当前需求用上面的方法已经足够简洁高效了。

内容的提问来源于stack exchange,提问作者aircraft

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:07:19