Fix small regression caused by 71ada3a8e6
.
During direct assignment, evaluating the iterable before the transaction is started avoids leaving the transaction dirty if an exception is raised. This is slightly more wasteful but probably not enough to warrant a change of behavior. Thanks Anssi for the feedback. Refs #6707.
This commit is contained in:
parent
9d104a21e2
commit
20eb51ce0d
|
@ -554,15 +554,15 @@ def create_generic_related_manager(superclass):
|
||||||
_clear.alters_data = True
|
_clear.alters_data = True
|
||||||
|
|
||||||
def set(self, objs, **kwargs):
|
def set(self, objs, **kwargs):
|
||||||
|
# Force evaluation of `objs` in case it's a queryset whose value
|
||||||
|
# could be affected by `manager.clear()`. Refs #19816.
|
||||||
|
objs = tuple(objs)
|
||||||
|
|
||||||
clear = kwargs.pop('clear', False)
|
clear = kwargs.pop('clear', False)
|
||||||
|
|
||||||
db = router.db_for_write(self.model, instance=self.instance)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
with transaction.atomic(using=db, savepoint=False):
|
with transaction.atomic(using=db, savepoint=False):
|
||||||
if clear:
|
if clear:
|
||||||
# Force evaluation of `objs` in case it's a queryset whose value
|
|
||||||
# could be affected by `manager.clear()`. Refs #19816.
|
|
||||||
objs = tuple(objs)
|
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
self.add(*objs)
|
self.add(*objs)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -797,16 +797,16 @@ def create_foreign_related_manager(superclass, rel_field, rel_model):
|
||||||
_clear.alters_data = True
|
_clear.alters_data = True
|
||||||
|
|
||||||
def set(self, objs, **kwargs):
|
def set(self, objs, **kwargs):
|
||||||
|
# Force evaluation of `objs` in case it's a queryset whose value
|
||||||
|
# could be affected by `manager.clear()`. Refs #19816.
|
||||||
|
objs = tuple(objs)
|
||||||
|
|
||||||
clear = kwargs.pop('clear', False)
|
clear = kwargs.pop('clear', False)
|
||||||
|
|
||||||
if rel_field.null:
|
if rel_field.null:
|
||||||
db = router.db_for_write(self.model, instance=self.instance)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
with transaction.atomic(using=db, savepoint=False):
|
with transaction.atomic(using=db, savepoint=False):
|
||||||
if clear:
|
if clear:
|
||||||
# Force evaluation of `objs` in case it's a queryset whose value
|
|
||||||
# could be affected by `manager.clear()`. Refs #19816.
|
|
||||||
objs = tuple(objs)
|
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
self.add(*objs)
|
self.add(*objs)
|
||||||
else:
|
else:
|
||||||
|
@ -1029,15 +1029,15 @@ def create_many_related_manager(superclass, rel):
|
||||||
(opts.app_label, opts.object_name)
|
(opts.app_label, opts.object_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Force evaluation of `objs` in case it's a queryset whose value
|
||||||
|
# could be affected by `manager.clear()`. Refs #19816.
|
||||||
|
objs = tuple(objs)
|
||||||
|
|
||||||
clear = kwargs.pop('clear', False)
|
clear = kwargs.pop('clear', False)
|
||||||
|
|
||||||
db = router.db_for_write(self.through, instance=self.instance)
|
db = router.db_for_write(self.through, instance=self.instance)
|
||||||
with transaction.atomic(using=db, savepoint=False):
|
with transaction.atomic(using=db, savepoint=False):
|
||||||
if clear:
|
if clear:
|
||||||
# Force evaluation of `objs` in case it's a queryset whose value
|
|
||||||
# could be affected by `manager.clear()`. Refs #19816.
|
|
||||||
objs = tuple(objs)
|
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
self.add(*objs)
|
self.add(*objs)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue