summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <simon.charette@zapier.com>2019-10-06 21:48:14 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-10-09 09:49:53 +0200
commit44522d1036604e13a5adf4e084e1c8f7b56c82c0 (patch)
tree520d7c5ac5dc983da86afaf98f75cd28b4a0b4a3
parent832aa08afecee4f59cb480c4e4a6b29bcbb22b94 (diff)
Made Collector.collect() return immediately for disabled related collection.
-rw-r--r--django/db/models/deletion.py77
1 files changed, 40 insertions, 37 deletions
diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
index 02dfc43e40..398da5cbb6 100644
--- a/django/db/models/deletion.py
+++ b/django/db/models/deletion.py
@@ -210,43 +210,46 @@ class Collector:
source_attr=ptr.remote_field.related_name,
collect_related=False,
reverse_dependency=True)
- if collect_related:
- if keep_parents:
- parents = set(model._meta.get_parent_list())
- for related in get_candidate_relations_to_delete(model._meta):
- # Preserve parent reverse relationships if keep_parents=True.
- if keep_parents and related.model in parents:
- continue
- field = related.field
- if field.remote_field.on_delete == DO_NOTHING:
- continue
- batches = self.get_del_batches(new_objs, field)
- for batch in batches:
- sub_objs = self.related_objects(related, batch)
- if self.can_fast_delete(sub_objs, from_field=field):
- self.fast_deletes.append(sub_objs)
- else:
- related_model = related.related_model
- # Non-referenced fields can be deferred if no signal
- # receivers are connected for the related model as
- # they'll never be exposed to the user. Skip field
- # deferring when some relationships are select_related
- # as interactions between both features are hard to
- # get right. This should only happen in the rare
- # cases where .related_objects is overridden anyway.
- if not (sub_objs.query.select_related or self._has_signal_listeners(related_model)):
- referenced_fields = set(chain.from_iterable(
- (rf.attname for rf in rel.field.foreign_related_fields)
- for rel in get_candidate_relations_to_delete(related_model._meta)
- ))
- sub_objs = sub_objs.only(*tuple(referenced_fields))
- if sub_objs:
- field.remote_field.on_delete(self, field, sub_objs, self.using)
- for field in model._meta.private_fields:
- if hasattr(field, 'bulk_related_objects'):
- # It's something like generic foreign key.
- sub_objs = field.bulk_related_objects(new_objs, self.using)
- self.collect(sub_objs, source=model, nullable=True)
+ if not collect_related:
+ return
+
+ if keep_parents:
+ parents = set(model._meta.get_parent_list())
+ for related in get_candidate_relations_to_delete(model._meta):
+ # Preserve parent reverse relationships if keep_parents=True.
+ if keep_parents and related.model in parents:
+ continue
+ field = related.field
+ if field.remote_field.on_delete == DO_NOTHING:
+ continue
+ batches = self.get_del_batches(new_objs, field)
+ for batch in batches:
+ sub_objs = self.related_objects(related, batch)
+ if self.can_fast_delete(sub_objs, from_field=field):
+ self.fast_deletes.append(sub_objs)
+ else:
+ related_model = related.related_model
+ # Non-referenced fields can be deferred if no signal
+ # receivers are connected for the related model as
+ # they'll never be exposed to the user. Skip field
+ # deferring when some relationships are select_related
+ # as interactions between both features are hard to
+ # get right. This should only happen in the rare
+ # cases where .related_objects is overridden anyway.
+ if not (sub_objs.query.select_related or self._has_signal_listeners(related_model)):
+ referenced_fields = set(chain.from_iterable(
+ (rf.attname for rf in rel.field.foreign_related_fields)
+ for rel in get_candidate_relations_to_delete(related_model._meta)
+ ))
+ sub_objs = sub_objs.only(*tuple(referenced_fields))
+ if sub_objs:
+ field.remote_field.on_delete(self, field, sub_objs, self.using)
+
+ for field in model._meta.private_fields:
+ if hasattr(field, 'bulk_related_objects'):
+ # It's something like generic foreign key.
+ sub_objs = field.bulk_related_objects(new_objs, self.using)
+ self.collect(sub_objs, source=model, nullable=True)
def related_objects(self, related, objs):
"""