Ticket #6870: 6870.pre_delete. r13248.diff

File 6870.pre_delete. r13248.diff, 5.2 KB (added by cgieringer, 5 years ago)

Adds a pre_signal argument to _collect_sub_objects to allow the notification of listeners to pre_deletes before related objects are collected.

  • django/db/models/base.py

    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index 6304e00..3a4d5c2 100644
    a b class Model(object): 
    544544
    545545    save_base.alters_data = True
    546546
    547     def _collect_sub_objects(self, seen_objs, parent=None, nullable=False):
     547    def _collect_sub_objects(self, seen_objs, parent=None, nullable=False, pre_signal=None):
    548548        """
    549549        Recursively populates seen_objs with all objects related to this
    550550        object.
    class Model(object): 
    553553            [(model_class, {pk_val: obj, pk_val: obj, ...}),
    554554             (model_class, {pk_val: obj, pk_val: obj, ...}), ...]
    555555        """
     556        if not pre_signal is None and not self.__class__._meta.auto_created:
     557            pre_signal.send(sender=self.__class__, instance=self)
    556558        pk_val = self._get_pk_val()
    557559        if seen_objs.add(self.__class__, pk_val, self,
    558560                         type(parent), parent, nullable):
    class Model(object): 
    566568                except ObjectDoesNotExist:
    567569                    pass
    568570                else:
    569                     sub_obj._collect_sub_objects(seen_objs, self, related.field.null)
     571                    sub_obj._collect_sub_objects(seen_objs, self, related.field.null, pre_signal)
    570572            else:
    571573                # To make sure we can access all elements, we can't use the
    572574                # normal manager on the related object. So we work directly
    class Model(object): 
    584586                        continue
    585587                delete_qs = rel_descriptor.delete_manager(self).all()
    586588                for sub_obj in delete_qs:
    587                     sub_obj._collect_sub_objects(seen_objs, self, related.field.null)
     589                    sub_obj._collect_sub_objects(seen_objs, self, related.field.null, pre_signal)
    588590
    589591        for related in self._meta.get_all_related_many_to_many_objects():
    590592            if related.field.rel.through:
    class Model(object): 
    594596                nullable = opts.get_field(reverse_field_name).null
    595597                filters = {reverse_field_name: self}
    596598                for sub_obj in related.field.rel.through._base_manager.using(db).filter(**filters):
    597                     sub_obj._collect_sub_objects(seen_objs, self, nullable)
     599                    sub_obj._collect_sub_objects(seen_objs, self, nullable, pre_signal)
    598600
    599601        for f in self._meta.many_to_many:
    600602            if f.rel.through:
    class Model(object): 
    604606                nullable = opts.get_field(field_name).null
    605607                filters = {field_name: self}
    606608                for sub_obj in f.rel.through._base_manager.using(db).filter(**filters):
    607                     sub_obj._collect_sub_objects(seen_objs, self, nullable)
     609                    sub_obj._collect_sub_objects(seen_objs, self, nullable, pre_signal)
    608610            else:
    609611                # m2m-ish but with no through table? GenericRelation: cascade delete
    610612                for sub_obj in f.value_from_object(self).all():
    611613                    # Generic relations not enforced by db constraints, thus we can set
    612614                    # nullable=True, order does not matter
    613                     sub_obj._collect_sub_objects(seen_objs, self, True)
     615                    sub_obj._collect_sub_objects(seen_objs, self, True, pre_signal)
    614616
    615617        # Handle any ancestors (for the model-inheritance case). We do this by
    616618        # traversing to the most remote parent classes -- those with no parents
    class Model(object): 
    625627                continue
    626628            # At this point, parent_obj is base class (no ancestor models). So
    627629            # delete it and all its descendents.
    628             parent_obj._collect_sub_objects(seen_objs)
     630            parent_obj._collect_sub_objects(seen_objs, pre_signal=pre_signal)
    629631
    630632    def delete(self, using=None):
    631633        using = using or router.db_for_write(self.__class__, instance=self)
    class Model(object): 
    633635
    634636        # Find all the objects than need to be deleted.
    635637        seen_objs = CollectedObjects()
    636         self._collect_sub_objects(seen_objs)
     638        self._collect_sub_objects(seen_objs, pre_signal=signals.pre_delete)
    637639
    638640        # Actually delete the objects.
    639641        delete_objects(seen_objs, using)
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index d9fbd9b..b9947b7 100644
    a b class QuerySet(object): 
    438438            # need to maintain the query cache on del_query (see #12328)
    439439            seen_objs = CollectedObjects(seen_objs)
    440440            for i, obj in izip(xrange(CHUNK_SIZE), del_itr):
    441                 obj._collect_sub_objects(seen_objs)
     441                obj._collect_sub_objects(seen_objs, pre_signal=signals.pre_delete)
    442442
    443443            if not seen_objs:
    444444                break
    def delete_objects(seen_objs, using): 
    13081308            items.sort()
    13091309            obj_pairs[cls] = items
    13101310
    1311             # Pre-notify all instances to be deleted.
    1312             for pk_val, instance in items:
    1313                 if not cls._meta.auto_created:
    1314                     signals.pre_delete.send(sender=cls, instance=instance)
    1315 
    13161311            pk_list = [pk for pk,instance in items]
    13171312
    13181313            update_query = sql.UpdateQuery(cls)
Back to Top