如何用Django基础命令实现数据更新与新增?解决重复创建问题
解决Django update_or_create重复创建数据的问题
你遇到的问题核心是错误使用了update_or_create的参数结构,导致每次触发命令时,系统把rate也当作了匹配现有记录的条件,而不是仅用唯一标识字段去匹配、更新rate值。
问题原因
update_or_create的逻辑是:用第一个参数里的字段匹配现有记录,如果匹配到就更新defaults里的字段;如果匹配不到,就创建包含所有查询字段+defaults字段的新记录。
你的代码里把需要更新的rate也放到了查询条件里:
CoronaAge.objects.update_or_create( age=title['age'], rate=title['rate'] # 错误:把更新字段当成了查询条件 )
这样一来,只要接口返回的rate值有变化,或者首次创建后再次触发命令,系统会因为找不到同时匹配age和rate的记录,直接创建新数据,最终导致重复。
修正后的代码
正确的做法是把唯一标识字段(比如age、sex、condition)作为查询条件,将需要更新的rate放到defaults字典中:
from django.core.management.base import BaseCommand import requests from demo.models import CoronaAge, CoronaSex, CoronaComorbidity class Command(BaseCommand): def handle(self, *args, **kwargs): url = 'https://api.the2019ncov.com/api/fatality-rate' r = requests.get(url) titles = r.json() print(titles) # 按年龄统计数据 for title in titles.get('byAge', []): CoronaAge.objects.update_or_create( age=title['age'], # 唯一匹配条件 defaults={'rate': title['rate']} # 需要更新的字段 ) # 按性别统计数据 for title in titles.get('bySex', []): CoronaSex.objects.update_or_create( sex=title['sex'], defaults={'rate': title['rate']} ) # 按基础病统计数据 for title in titles.get('byComorbidity', []): CoronaComorbidity.objects.update_or_create( condition=title['preExistingCondition'], defaults={'rate': title['rate']} )
额外优化点
- 用
titles.get('byAge', [])替代titles['byAge'] or [],避免接口返回的键不存在时抛出KeyError,代码更健壮; - 移除了未使用的
context变量,精简代码。
修改后,每次触发命令时:
- 系统会先根据唯一标识字段查找现有记录;
- 找到则更新
rate字段,找不到则创建新记录,彻底解决重复数据问题。
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

