mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
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()
|
return update_fields is not None or filtered.exists()
|
||||||
if self._meta.select_on_save and not forced_update:
|
if self._meta.select_on_save and not forced_update:
|
||||||
if filtered.exists():
|
if filtered.exists():
|
||||||
filtered._update(values)
|
# It may happen that the object is deleted from the DB right after
|
||||||
return True
|
# 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:
|
else:
|
||||||
return False
|
return False
|
||||||
return filtered._update(values) > 0
|
return filtered._update(values) > 0
|
||||||
|
@ -701,7 +701,7 @@ class SelectOnSaveTests(TestCase):
|
|||||||
try:
|
try:
|
||||||
Article._base_manager.__class__ = FakeManager
|
Article._base_manager.__class__ = FakeManager
|
||||||
asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
|
asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
|
||||||
with self.assertNumQueries(2):
|
with self.assertNumQueries(3):
|
||||||
asos.save()
|
asos.save()
|
||||||
self.assertTrue(FakeQuerySet.called)
|
self.assertTrue(FakeQuerySet.called)
|
||||||
# This is not wanted behavior, but this is how Django has always
|
# This is not wanted behavior, but this is how Django has always
|
||||||
|
Loading…
x
Reference in New Issue
Block a user