Commit 20eb51ce authored by Loic Bistuer's avatar Loic Bistuer
Browse files

Fix small regression caused by 71ada3a8.

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.
parent 9d104a21
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -554,15 +554,15 @@ def create_generic_related_manager(superclass):
        _clear.alters_data = True

        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)

            db = router.db_for_write(self.model, instance=self.instance)
            with transaction.atomic(using=db, savepoint=False):
                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.add(*objs)
                else:
+8 −8
Original line number Diff line number Diff line
@@ -797,16 +797,16 @@ def create_foreign_related_manager(superclass, rel_field, rel_model):
            _clear.alters_data = True

        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)

            if rel_field.null:
                db = router.db_for_write(self.model, instance=self.instance)
                with transaction.atomic(using=db, savepoint=False):
                    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.add(*objs)
                    else:
@@ -1029,15 +1029,15 @@ def create_many_related_manager(superclass, rel):
                    (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)

            db = router.db_for_write(self.through, instance=self.instance)
            with transaction.atomic(using=db, savepoint=False):
                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.add(*objs)
                else: