Fixed #22967 -- Made Model._do_update consistent
Made _do_update behave more strictly according to its docs, including a corner case when specific concurent updates are executed and select_on_save is set.
This commit is contained in:
parent
d647764a53
commit
c56c42b5c0
|
@ -757,8 +757,14 @@ class Model(six.with_metaclass(ModelBase)):
|
|||
return update_fields is not None or filtered.exists()
|
||||
if self._meta.select_on_save and not forced_update:
|
||||
if filtered.exists():
|
||||
filtered._update(values)
|
||||
return True
|
||||
# It may happen that the object is deleted from the DB right after
|
||||
# this check, causing the subsequent UPDATE to return zero matching
|
||||
# rows. The same result can occur in some rare cases when the
|
||||
# database returns zero despite the UPDATE being executed
|
||||
# successfully (a row is matched and updated). In order to
|
||||
# distinguish these two cases, the object's existence in the
|
||||
# database is again checked for if the UPDATE query returns 0.
|
||||
return filtered._update(values) > 0 or filtered.exists()
|
||||
else:
|
||||
return False
|
||||
return filtered._update(values) > 0
|
||||
|
|
|
@ -701,7 +701,7 @@ class SelectOnSaveTests(TestCase):
|
|||
try:
|
||||
Article._base_manager.__class__ = FakeManager
|
||||
asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
|
||||
with self.assertNumQueries(2):
|
||||
with self.assertNumQueries(3):
|
||||
asos.save()
|
||||
self.assertTrue(FakeQuerySet.called)
|
||||
# This is not wanted behavior, but this is how Django has always
|
||||
|
|
Loading…
Reference in New Issue