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

Django DRF自定义过滤器报filter_name__icontains未定义解决方案

报错原因

你触发NameError的根本原因是字典键的写法不符合Python语法规则:当你写{filter_name__icontains: term.get(filter_name)}时,Python解释器会将filter_name__icontains识别为一个独立的变量名尝试取值,不会自动将filter_name变量的内容和__icontains后缀做拼接,由于代码里从来没有定义过叫这个名字的变量,自然会抛出未定义的报错。

修复方案

Django ORM的字段查找表达式本质是字符串格式的键,你只需要通过字符串拼接/f-string的方式,提前把字段名和查找后缀拼成完整的字符串键,再传给filter方法即可。
另外原代码中直接对比__class__判断字段类型的写法存在兼容问题,换成isinstance判断可以覆盖所有CharField的子类字段(比如EmailField、URLField、SlugField等),同时可以补充空值跳过逻辑,避免传入空过滤值时生成无效查询。

修正后的完整代码如下:

from django.db.models import QuerySet, CharField
from rest_framework.filters import BaseFilterBackend
from rest_framework.request import Request


class AbstractFilterBackend(BaseFilterBackend):
    @staticmethod
    def __execute_default_filters(queryset, terms: list):
        for term in terms:
            filter_name = next(iter(term.keys()))
            filter_value = term.get(filter_name)

            # 跳过空过滤值,避免无效查询
            if not filter_value:
                continue

            if hasattr(queryset.model, filter_name):
                model_field = queryset.model._meta.get_field(filter_name)
                # CharField类型字段使用icontains模糊匹配
                if isinstance(model_field, CharField):
                    lookup_key = f"{filter_name}__icontains"
                else:
                    lookup_key = filter_name
                queryset = queryset.filter(**{lookup_key: filter_value})

        return queryset
关键改动说明
  • 用f-string生成字段名__icontains格式的字符串作为查询键,解决变量识别错误的问题
  • 字段类型判断改用isinstance,兼容CharField子类字段
  • 新增空值判断逻辑,过滤空参数场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:06:11