使用Django update_or_create时遇TypeError参数重复错误求助
解决Django update_or_create的TypeError错误
问题场景
环境:Django 2.2.5、Python 3.7
调用update_or_create()时触发错误:TypeError: update_or_create() got multiple values for keyword argument 'dcf_ide'
更新前DataCorrectionForm模型数据:
dcf_ide pat status crated_date 0 43_inc_poi_1 01-001 1 2022-10-04 08:36:21.991740+00:00 1 43_inc_poi_3 01-003 1 2022-10-04 08:36:22.031926+00:00 2 43_inc_poi_7 02-001 1 2022-10-04 08:36:22.054673+00:00 3 43_inc_poi_9 01-050 1 2022-10-04 08:36:22.075715+00:00 4 43_inc_poi_11 01-002 1 2022-10-04 08:36:22.096237+00:00 5 46_inc_tai_2 02-002 1 2022-10-04 08:36:22.147911+00:00 6 46_inc_tai_4 01-004 1 2022-10-04 08:36:22.175169+00:00 7 46_inc_tai_7 02-001 1 2022-10-04 08:36:22.193514+00:00 8 46_inc_tai_9 01-050 1 2022-10-04 08:36:22.210608+00:00
执行的错误代码:
records = DCF_AFTER_UPDATE.to_dict(orient='records') for record in records: DataCorrectionForm.objects.update_or_create( dcf_ide=record['dcf_ide'], **record )
期望效果:更新已有记录的status字段,新增两条记录,目标数据:
dcf_ide pat status crated_date 0 43_inc_poi_1 01-001 0 2022-10-04 08:36:21.991740+00:00 #<= update status column 1 43_inc_poi_3 01-003 2 2022-10-04 08:36:22.031926+00:00 #<= update status column 2 43_inc_poi_7 02-001 2 2022-10-04 08:36:22.054673+00:00 #<= update status column 3 43_inc_poi_9 01-050 2 2022-10-04 08:36:22.075715+00:00 #<= update status column 4 43_inc_poi_11 01-002 2 2022-10-04 08:36:22.096237+00:00 #<= update status column 5 46_inc_tai_2 02-002 2 2022-10-04 08:36:22.147911+00:00 #<= update status column 6 46_inc_tai_4 01-004 2 2022-10-04 08:36:22.175169+00:00 #<= update status column 7 46_inc_tai_7 02-001 0 2022-10-04 08:36:22.193514+00:00 #<= update status column 8 46_inc_tai_9 01-050 2 2022-10-04 08:36:22.210608+00:00 #<= update status column 1 43_inc_poi_2 02-002 1 2022-10-04 10:00:02.896153+00:00 #<= create row 0 46_inc_tai_1 01-001 1 2022-10-04 10:00:10.937815+00:00 #<= create row
错误原因
你在调用update_or_create()时,既显式传递了dcf_ide=record['dcf_ide'],又通过**record展开了包含dcf_ide的字典,导致同一个参数被重复传递,触发TypeError。
update_or_create()的正确逻辑是:第一个参数组为查询条件(判断记录是否存在),通过defaults参数传递要更新/创建的字段数据。
修正代码
方式一:拆分查询条件与更新字段
records = DCF_AFTER_UPDATE.to_dict(orient='records') for record in records: # 提取查询条件并从原字典移除 lookup = {'dcf_ide': record.pop('dcf_ide')} # 执行更新或创建 DataCorrectionForm.objects.update_or_create( **lookup, defaults=record )
通过pop把dcf_ide从原字典中分离作为查询条件,剩余字段全部传入defaults,既避免重复传参,又能实现更新/创建逻辑。
方式二:构造不含查询条件的defaults字典
如果不想修改原record字典,可使用字典推导式排除查询字段:
records = DCF_AFTER_UPDATE.to_dict(orient='records') for record in records: DataCorrectionForm.objects.update_or_create( dcf_ide=record['dcf_ide'], defaults={k: v for k, v in record.items() if k != 'dcf_ide'} )
两种方式均能实现需求:
- 当
dcf_ide对应记录存在时,更新defaults中的字段(如status) - 当
dcf_ide对应记录不存在时,创建包含所有字段的新记录
内容的提问来源于stack exchange,提问作者Mereva
相关产品推荐
相关产品推荐

