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

如何在Django filter()方法中传入json_values字典过滤模型数据

Django filter方法传入字典键值对实现查询的方案

Django ORM的filter()原生支持通过**解包字典的方式传入查询条件,你持有的json_values本身就是「模型字段名-匹配值」结构的字典,直接解包传入即可完成过滤。

需要注意你原有代码里存在两处逻辑bug,会导致更新已有对象的逻辑失效,需要一并修正:

  • 原代码中判断对象是否存在的exists()调用没有传入过滤条件,会直接判断整张表是否有任意数据,不符合业务逻辑
  • 原代码查询到已存在的retrieved_object后,直接将变量重新赋值为传入的新model实例,导致之前的查询完全失效,不会更新已有数据

修正后的完整逻辑代码

def upload_object_values(model, json_values, update_if_exists=True):
    if json_values:
        # 拷贝字典避免遍历过程中修改原字典报错
        valid_query_params = json_values.copy()
        # 移除id类字段,不作为匹配条件
        for key in list(valid_query_params.keys()):
            if key.endswith('_id') or key == 'id':
                valid_query_params.pop(key)

        # 给传入的新实例先赋值字段
        for key, value in valid_query_params.items():
            setattr(model, key, value)
        
        if update_if_exists:
            # 解包字典传入filter,生成统一查询集
            matched_queryset = model.__class__.objects.seal().filter(**valid_query_params)
            if matched_queryset.exists():
                # 取出已存在的记录
                existing_obj = matched_queryset.first()
                # 将新的字段值更新到已存在的记录上
                for key, value in valid_query_params.items():
                    setattr(existing_obj, key, value)
                existing_obj.save()
                print(existing_obj)
                print('existing, saved successfully')
            else:
                # 无匹配记录,直接保存新实例
                model.save()
                print('does not exist, saved successfully')
        else:
            model.save()
            print('created successfully')

说明

  • 传入的示例数据{'notes': '', 'name': 'test issuer', 'phone': None}解包后等价于调用.filter(notes='', name='test issuer', phone=None),Django会自动将phone=None翻译为SQL中的phone IS NULL查询,不需要额外处理空值
  • 建议将过滤用的参数字典单独存为变量,避免exists()和filter()两次调用传入的条件不一致
  • 遍历字典删除键的时候,建议遍历字典的键列表副本,避免迭代过程中字典长度变化触发运行时报错

内容的提问来源于stack exchange,提问作者Prosy A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:51:27