List Info

Thread: Get all related instances




Get all related instances
user name
2007-10-22 08:03:21
Hi,

since obj.delete() uses "on delete cascade", I
want to see first
which instances still have a reference to obj (and would get
deleted).

I write this little helper. Comments welcome:

def all_related_instances(instance):
    """
    Return all instances which have a relation to this
instance.
    You can check this list before instance.delete(), since
all returned
    instances would get deleted, too (ON DELETE CASCADE)
    """
    assert isinstance(instance, models.Model)
    meta=instance._meta
    related=[]
    for related_object in
meta.get_all_related_objects()+meta.get_all_related_many_to_
many_objects():
        attr = getattr(instance,
related_object.get_accessor_name())
        related.extend(attr.all())
    return related


-- 
Thomas Güttler, http://www.tbz-pariv.de/

Bernsdorfer Str. 210-212, 09126 Chemnitz, Tel.:
0371/5347-917
TBZ-PARIV GmbH  Geschäftsführer: Dr. Reiner Wohlgemuth
Sitz der Gesellschaft: Chemnitz Registergericht: Chemnitz
HRB 8543

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "Django users" group.
To post to this group, send email to django-usersgooglegroups.com
To unsubscribe from this group, send email to
django-users-unsubscribegooglegroups.com
For more options, visit this group at htt
p://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Get all related instances
country flaguser name
Australia
2007-10-22 08:10:24
On Mon, 2007-10-22 at 15:03 +0200, Thomas Güttler wrote:
> Hi,
> 
> since obj.delete() uses "on delete cascade",
I want to see first
> which instances still have a reference to obj (and
would get deleted).
> 
> I write this little helper. Comments welcome:
> 
> def all_related_instances(instance):
>     """
>     Return all instances which have a relation to this
instance.
>     You can check this list before instance.delete(),
since all returned
>     instances would get deleted, too (ON DELETE
CASCADE)
>     """
>     assert isinstance(instance, models.Model)
>     meta=instance._meta
>     related=[]
>     for related_object in
meta.get_all_related_objects()+meta.get_all_related_many_to_
many_objects():
>         attr = getattr(instance,
related_object.get_accessor_name())
>         related.extend(attr.all())
>     return related

That would seem to only account for things that are directly
attached to
the current model, rather than more distant relations.

Have a look at what Model._collect_sub_objects() does -- or
call it
directly -- to see how Django goes about collecting all the
objects for
deletion. That method is seeded with an empty SortedDict()
from
Model.delete().

Regards,
Malcoml

-- 
Depression is merely anger without enthusiasm. 
http://www.pointy-s
tick.com/blog/


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "Django users" group.
To post to this group, send email to django-usersgooglegroups.com
To unsubscribe from this group, send email to
django-users-unsubscribegooglegroups.com
For more options, visit this group at htt
p://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Get all related instances
user name
2007-10-22 09:31:30
Hi Malcom and other,

> That would seem to only account for things that are
directly attached to
> the current model, rather than more distant relations.

Yes, but that's enough for me.

> Have a look at what Model._collect_sub_objects() does
-- or call it
> directly -- to see how Django goes about collecting all
the objects for
> deletion. That method is seeded with an empty
SortedDict() from
> Model.delete().

I looked at it. It ignores many to many relations.

self._meta.get_all_related_objects() does not return them.

BTW, why does django collect all sub objects? The SQL part
"ON DELETE CASCADE" should
remove them.

Here is the unmodified django code:
"""
    def _collect_sub_objects(self, seen_objs):
        """
        Recursively populates seen_objs with all objects
related to this object.
        When done, seen_objs will be in the format:
            {model_class: {pk_val: obj, pk_val: obj, ...},
             model_class: {pk_val: obj, pk_val: obj, ...},
...}
        """
        pk_val = self._get_pk_val()
        if pk_val in seen_objs.setdefault(self.__class__,
{}):
            return
        seen_objs.setdefault(self.__class__, {})[pk_val] =
self

        for related in
self._meta.get_all_related_objects():
            rel_opts_name = related.get_accessor_name()
            if isinstance(related.field.rel, OneToOneRel):
                try:
                    sub_obj = getattr(self, rel_opts_name)
                except ObjectDoesNotExist:
                    pass
                else:
                    sub_obj._collect_sub_objects(seen_objs)
            else:
                for sub_obj in getattr(self,
rel_opts_name).all():
                    sub_obj._collect_sub_objects(seen_objs)
"""

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "Django users" group.
To post to this group, send email to django-usersgooglegroups.com
To unsubscribe from this group, send email to
django-users-unsubscribegooglegroups.com
For more options, visit this group at htt
p://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Get all related instances
user name
2007-10-22 09:45:41
On 10/22/07, Thomas Guettler < hvtbz-pariv.de">hvtbz-pariv.de> wrote:
BTW, why does django collect all sub objects? The SQL part "ON DELETE CASCADE&quot; should
remove them.

Not all the database backends will do the cascading delete.&nbsp; MySQL, for instance, only supports it for certain kinds of tables.&nbsp; So Django does the work upfront so that delete behaves the same regardless of the limitations of the backend in use.

Karen
 


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django users"; group.
To post to this group, send email to django-usersgooglegroups.com
To unsubscribe from this group, send email to django-users-unsubscribegooglegroups.com
For more options, visit this group at http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Re: Get all related instances
country flaguser name
Australia
2007-10-22 20:09:32
On Mon, 2007-10-22 at 16:31 +0200, Thomas Guettler wrote:
[...]
> BTW, why does django collect all sub objects? The SQL
part "ON DELETE CASCADE" should
> remove them.

pre_delete and post_delete signals.

Regards,
Malcolm

-- 
Borrow from a pessimist - they don't expect it back. 
http://www.pointy-s
tick.com/blog/


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "Django users" group.
To post to this group, send email to django-usersgooglegroups.com
To unsubscribe from this group, send email to
django-users-unsubscribegooglegroups.com
For more options, visit this group at htt
p://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---


[1-5]

about | contact  Other archives ( Real Estate discussion Medical topics )