先上源码:
1.注释解释是根据**kwargs去查,如果对象查到就更新一个对象,否则就创建一个对象
此外这里引用到行锁概念,阻塞当前查询对象的更新直到update_or_create() 调用save()方法结束;
整个操作是在一个事务里执行证明是可回滚的
源码select_for_update方法返回的是一个查询集合的queryset
def select_for_update(self, nowait=False, skip_locked=False, of=()):
"""
Return a new QuerySet instance that will select objects with a
FOR UPDATE lock.
"""
if nowait and skip_locked:
raise ValueError('The nowait option cannot be used with skip_locked.')
obj = self._chain()
obj._for_write = True
obj.query.select_for_update = True
obj.query.select_for_update_nowait = nowait
obj.query.select_for_update_skip_locked = skip_locked
obj.query.select_for_update_of = of
return obj
其次进行kwargs和default预创建对象参数检验:使用_extract_model_params()
如果没查到就用通过校验的预创建对象参数创建一个对象:
否则就返回查询到的对象,进行defaults参数更新,通过setattr(obj,key,value)
for k, v in defaults.items():
setattr(obj, k, v() if callable(v) else v)
obj.save(using=self.db)
总结:根据kwargs查询,查到就用defaults里面的参数解包更新并且返回否则就用defaults里面参数和kwargs参数进行update合并生成新的对象并创建返回这个创建对象