Django QuerySet filter传入动态自定义参数报FieldError如何解决
问题根因
Django ORM的filter()方法接收关键字参数时,等号左侧的标识符会被直接识别为硬编码的模型字段名,不会读取同名变量的存储值。代码中filter(column=val)的写法,实际是要求ORM查询column字段等于val的记录,完全不会使用前面从请求参数中获取到的column变量的动态值,因此会因模型不存在column字段抛出FieldError。
修复方案
通过Python的**字典解包语法传参即可:把动态字段名作为字典的键,匹配值作为字典的值,解包后传入filter(),ORM就会正确识别动态字段名。
基础修复代码如下:
def get(self, request): column = request.query_params.get('column') val = request.query_params.get('value') # 字典解包传入动态查询条件 query = Data.objects.filter(**{column: val}).values() serializer = DataSerializer(query, many=True).data return Response(serializer)
如果需要使用其他查询规则(模糊匹配、范围查询、大小比较等),只需要在字典的key上拼接Django ORM支持的查询后缀即可,例如对动态字段做模糊匹配的写法为**{f"{column}__icontains": val}。
必做安全加固
直接透传前端传入的字段名存在安全风险,必须配置查询字段白名单,避免攻击者传入非法字段名(比如关联表敏感字段、不存在的字段)造成数据泄露或接口异常,加固后代码参考:
def get(self, request): column = request.query_params.get('column') val = request.query_params.get('value') # 替换为你的模型中实际允许前端查询的字段列表 allowed_query_fields = ["name", "age", "status", "create_time"] if column not in allowed_query_fields: return Response({"msg": "查询字段不合法"}, status=400) query = Data.objects.filter(**{column: val}).values() serializer = DataSerializer(query, many=True).data return Response(serializer)
内容的提问来源于stack exchange,提问作者Mukul
相关产品推荐
相关产品推荐

