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

Django中查询参数为None时如何优雅实现模型数据过滤

Django 动态查询参数过滤的简洁实现

这是Django ORM使用中非常典型的动态过滤场景,写多层分支判断完全没必要,利用filter支持关键字参数解包的特性就能用非常简洁的代码实现,后续扩展过滤字段也很方便。

最简实现方案

核心逻辑是构造一个过滤条件字典,只把值非空(即参数实际传入了)的字段放进字典,最后把字典解包传给filter方法即可,代码如下:

def get(self, request):
    query = request.GET
    filter_kwargs = {}
    
    category_id = query.get('category_id')
    if category_id is not None:
        filter_kwargs['category_id'] = category_id
        
    level = query.get('level')
    if level is not None:
        filter_kwargs['level'] = level
    
    qs = Theme.objects.filter(**filter_kwargs)

注意避坑

不要用if category_id这种真值判断来决定是否加过滤条件:如果合法参数值是整数0,会被误判为假值跳过过滤,必须用is not None做判断才准确。

更易扩展的写法

如果后续要加更多过滤参数,还可以用字段白名单的方式循环处理,不用重复写判断逻辑:

def get(self, request):
    # 配置允许作为过滤条件的模型字段,避免传入非法参数导致安全问题
    allow_filter_fields = ["category_id", "level"]
    filter_kwargs = {}
    for field in allow_filter_fields:
        value = request.GET.get(field)
        if value is not None:
            filter_kwargs[field] = value
    qs = Theme.objects.filter(**filter_kwargs)

安全提示:必须维护过滤字段白名单,绝对不能直接把request.GET的所有键值对直接解包传给filter,否则会存在越权查询、SQL注入的风险。

如果项目中过滤场景比较复杂,也可以直接接入Django生态的django-filter库做统一的参数校验和过滤,但就当前的需求场景,上面的原生实现没有额外依赖,逻辑清晰完全够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:18:09