Loading django/db/models/base.py +15 −0 Original line number Diff line number Diff line Loading @@ -395,6 +395,21 @@ class Model(object): for sub_obj in getattr(self, rel_opts_name).all(): sub_obj._collect_sub_objects(seen_objs, self.__class__, related.field.null) # Handle any ancestors (for the model-inheritance case). We do this by # traversing to the most remote parent classes -- those with no parents # themselves -- and then adding those instances to the collection. That # will include all the child instances down to "self". parent_stack = self._meta.parents.values() while parent_stack: link = parent_stack.pop() parent_obj = getattr(self, link.name) if parent_obj._meta.parents: parent_stack.extend(parent_obj._meta.parents.values()) continue # At this point, parent_obj is base class (no ancestor models). So # delete it and all its descendents. parent_obj._collect_sub_objects(seen_objs) def delete(self): assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname) Loading tests/regressiontests/model_inheritance_regress/models.py +22 −0 Original line number Diff line number Diff line Loading @@ -131,4 +131,26 @@ __test__ = {'API_TESTS':""" >>> Child.objects.dates('created', 'month') [datetime.datetime(2008, 6, 1, 0, 0)] # Regression test for #7276: calling delete() on a model with multi-table # inheritance should delete the associated rows from any ancestor tables, as # well as any descendent objects. >>> ident = ItalianRestaurant.objects.all()[0].id >>> Place.objects.get(pk=ident) <Place: Guido's All New House of Pasta the place> >>> xx = Restaurant.objects.create(name='a', address='xx', serves_hot_dogs=True, serves_pizza=False) # This should delete both Restuarants, plus the related places, plus the ItalianRestaurant. >>> Restaurant.objects.all().delete() >>> Place.objects.get(pk=ident) Traceback (most recent call last): ... DoesNotExist: Place matching query does not exist. >>> ItalianRestaurant.objects.get(pk=ident) Traceback (most recent call last): ... DoesNotExist: ItalianRestaurant matching query does not exist. """} Loading
django/db/models/base.py +15 −0 Original line number Diff line number Diff line Loading @@ -395,6 +395,21 @@ class Model(object): for sub_obj in getattr(self, rel_opts_name).all(): sub_obj._collect_sub_objects(seen_objs, self.__class__, related.field.null) # Handle any ancestors (for the model-inheritance case). We do this by # traversing to the most remote parent classes -- those with no parents # themselves -- and then adding those instances to the collection. That # will include all the child instances down to "self". parent_stack = self._meta.parents.values() while parent_stack: link = parent_stack.pop() parent_obj = getattr(self, link.name) if parent_obj._meta.parents: parent_stack.extend(parent_obj._meta.parents.values()) continue # At this point, parent_obj is base class (no ancestor models). So # delete it and all its descendents. parent_obj._collect_sub_objects(seen_objs) def delete(self): assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname) Loading
tests/regressiontests/model_inheritance_regress/models.py +22 −0 Original line number Diff line number Diff line Loading @@ -131,4 +131,26 @@ __test__ = {'API_TESTS':""" >>> Child.objects.dates('created', 'month') [datetime.datetime(2008, 6, 1, 0, 0)] # Regression test for #7276: calling delete() on a model with multi-table # inheritance should delete the associated rows from any ancestor tables, as # well as any descendent objects. >>> ident = ItalianRestaurant.objects.all()[0].id >>> Place.objects.get(pk=ident) <Place: Guido's All New House of Pasta the place> >>> xx = Restaurant.objects.create(name='a', address='xx', serves_hot_dogs=True, serves_pizza=False) # This should delete both Restuarants, plus the related places, plus the ItalianRestaurant. >>> Restaurant.objects.all().delete() >>> Place.objects.get(pk=ident) Traceback (most recent call last): ... DoesNotExist: Place matching query does not exist. >>> ItalianRestaurant.objects.get(pk=ident) Traceback (most recent call last): ... DoesNotExist: ItalianRestaurant matching query does not exist. """}