Fixed #7276 -- Delete multi-table objects correctly.
When model inheritance is used, the parent objects should be deleted as part of the delete() call on the child. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7784 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
2c1d6a80b3
commit
4931639636
|
@ -395,6 +395,21 @@ class Model(object):
|
||||||
for sub_obj in getattr(self, rel_opts_name).all():
|
for sub_obj in getattr(self, rel_opts_name).all():
|
||||||
sub_obj._collect_sub_objects(seen_objs, self.__class__, related.field.null)
|
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):
|
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)
|
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)
|
||||||
|
|
||||||
|
|
|
@ -131,4 +131,26 @@ __test__ = {'API_TESTS':"""
|
||||||
>>> Child.objects.dates('created', 'month')
|
>>> Child.objects.dates('created', 'month')
|
||||||
[datetime.datetime(2008, 6, 1, 0, 0)]
|
[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…
Reference in New Issue