Ticket #27272: deletion.diff

File deletion.diff, 2.0 KB (added by Daniel Izquierdo, 8 years ago)
  • django/db/models/deletion.py

    diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
    index 3830052..77df47a 100644
    a b class Collector(object):  
    7878        # parent.
    7979        self.dependencies = {}  # {model: {models}}
    8080
     81        self.protected_errors = []
     82
    8183    def add(self, objs, source=None, nullable=False, reverse_dependency=False):
    8284        """
    8385        Adds 'objs' to the collection of objects to be deleted.  If the call is
    class Collector(object):  
    216218                    if self.can_fast_delete(sub_objs, from_field=field):
    217219                        self.fast_deletes.append(sub_objs)
    218220                    elif sub_objs:
    219                         field.remote_field.on_delete(self, field, sub_objs, self.using)
     221                        try:
     222                            field.remote_field.on_delete(self, field, sub_objs, self.using)
     223                        except ProtectedError as e:
     224                            self.protected_errors.append(e)
     225
    220226            for field in model._meta.private_fields:
    221227                if hasattr(field, 'bulk_related_objects'):
    222228                    # It's something like generic foreign key.
    223229                    sub_objs = field.bulk_related_objects(new_objs, self.using)
    224230                    self.collect(sub_objs, source=model, nullable=True)
    225231
     232            for error in self.protected_errors:
     233                not_deleted = [obj for obj in error.protected_objects if obj not in self.data.get(obj.__class__, [])]
     234                candidate_fast_deletes = [qs for qs in self.fast_deletes if qs.model == error.protected_objects[0].__class__]
     235
     236                for obj in not_deleted:
     237                    if not any(qs.filter(pk=obj.pk).exists() for qs in candidate_fast_deletes):
     238                        raise error
     239
    226240    def related_objects(self, related, objs):
    227241        """
    228242        Gets a QuerySet of objects related to ``objs`` via the relation ``related``.
Back to Top