Message from discussion
Feel free to test queryset-refactor branch
Received: by 10.35.39.1 with SMTP id r1mr3615034pyj.4.1208471647153;
Thu, 17 Apr 2008 15:34:07 -0700 (PDT)
Return-Path: <sco...@gmail.com>
Received: from rv-out-0506.google.com (rv-out-0506.google.com [209.85.198.237])
by mx.google.com with ESMTP id a28si11108525pye.0.2008.04.17.15.34.05;
Thu, 17 Apr 2008 15:34:07 -0700 (PDT)
Received-SPF: pass (google.com: domain of sco...@gmail.com designates 209.85.198.237 as permitted sender) client-ip=209.85.198.237;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of sco...@gmail.com designates 209.85.198.237 as permitted sender) smtp.mail=sco...@gmail.com; dkim=pass (test mode) header...@gmail.com
Received: by rv-out-0506.google.com with SMTP id k40so130448rvb.16
for <django-users@googlegroups.com>; Thu, 17 Apr 2008 15:34:05 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=domainkey-signature:received:received:message-id:from:to:in-reply-to:content-type:content-transfer-encoding:mime-version:subject:date:references:x-mailer;
bh=sAGxJbObvPptSG+9WnXmv/vQ2vEKJ4qhJrxxPvxA2Y8=;
b=F6tHm0StLAotNR202jqF/d7HWjH159vqGSVXj+WjChdBlwbo89K506Sa/XoTcKEkBl451+k7kOyzql6j1mr9cXuZ8ER1kPkvxPpOqiCOchfRNQTPH0JN7FjoUQMBhW9R0mkUWCS8nVBUhjY4lzh54giAxjitvV5IJJAOyWMVA+c=
DomainKey-Signature: a=rsa-sha1; c=nofws;
d=gmail.com; s=gamma;
h=message-id:from:to:in-reply-to:content-type:content-transfer-encoding:mime-version:subject:date:references:x-mailer;
b=KaM81GZEF4kVyVvqrjxFHDDT0JBAnW3QyKoUriust344t1ZA1g+e6vA5NpMxD57rZ515t20Kf49UA992M9w1fQDqzRgZnMb657JPTJAUEn+5ULjkznREAL3pl/bPAFQCgs7Au3l9HEwEXp9WGlCsHgYDWcdhQDrWVWY/zWuIqDY=
Received: by 10.141.123.4 with SMTP id a4mr1135470rvn.172.1208471645168;
Thu, 17 Apr 2008 15:34:05 -0700 (PDT)
Return-Path: <sco...@gmail.com>
Received: from ?192.168.0.196? ( [70.64.14.62])
by mx.google.com with ESMTPS id c20sm18929886rvf.3.2008.04.17.15.34.03
(version=TLSv1/SSLv3 cipher=OTHER);
Thu, 17 Apr 2008 15:34:04 -0700 (PDT)
Message-Id: <204AFC2C-05E7-438F-AF0F-CA945F0F6...@gmail.com>
From: scott lewis <sco...@gmail.com>
To: django-users@googlegroups.com
In-Reply-To: <6106438e0804171453k5a923ad1u10cb3e5a6b98b...@mail.gmail.com>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
Content-Transfer-Encoding: 7bit
Mime-Version: 1.0 (Apple Message framework v919.2)
Subject: Re: Feel free to test queryset-refactor branch
Date: Thu, 17 Apr 2008 16:34:01 -0600
References: <1208085814.17060.31.ca...@counterweight.tredinnick.org> <39512ceb-b528-45f3-b799-56ee35cb2...@p25g2000hsf.googlegroups.com> <6106438e0804171453k5a923ad1u10cb3e5a6b98b...@mail.gmail.com>
X-Mailer: Apple Mail (2.919.2)
On 2008-04-17, at 1553, Justin Fagnani wrote:
> Hey Malcolm,
>
> I've been using qs-rf for a while now with basically no problems.
> Excellent work.
>
> There's one thing that may a little odd that I stumbled on while
> trying to get some primitive polymorphism working:
>
> The first thing is that there seems to be no way to tell if an
> instance of a parent class has a child instance without trying the
> child reference and catching the DoesNotExist exception. For a class
> with multiple subclasses, this is a cumbersome, so I've been adding
> a _type field to parent classes that gets set in save() of the
> subclasses.
>
> Is there a better way to do this, or is this something that could be
> included? I know there's no way to determine whether or not a class
> will be subclassed in the future, so I wouldn't be surprised if the
> answer is no. But maybe there should be a documented pattern.
>
> The odd part is what happens with the child reference. parent.child
> obviously works as expected, and returns either an instance of Child
> or raises DoesNotExist. But for an instance of Child, .child always
> returns a reference to itself, so that c.child == c is always True.
> This makes sense on one hand, because c is also an instance of
> Parent, but on the other, Child doesn't have a subclass, so
> should .child be None?
>
> I haven't actually encountered this in any real life situation,
> because it's hard to end up with collection in Django where you have
> a mix of parent and child instances, so maybe it'll never be a
> problem.
>
> One additional thing is that in one case, I know which subclasses
> I'm interested in, and it'd be great to have a way to specify that a
> queryset should return polymorphic results by specifying the
> subclasses for the join. Something like:
>
> Parent.objects.all().select_subclasses('Child1','Child2')
This is a dirty hack, but it came in handy for me...
If you add this method to your parent class:
def canonical(self):
attr_name = '%s_ptr' % self._meta.module_name
children_fields = [r.get_accessor_name() for r in
self._meta.get_all_related_objects() if r.field.name == attr_name]
for f in children_fields:
try:
return getattr(self, f).canonical()
except models.ObjectDoesNotExist:
pass
return self
You can then convert a queryset to a list of child classes:
child_classes = [c.canonical() for c in Parent.objects.all()]
Basically, canonical() tries to grab a list of descendant classes,
then cycles through those until it finds one that exists. If it can't
find an instance of a descendant class, it just hands back the parent
since that's what you have. It's also recursive so it will traverse n-
levels of inheritance.
scott.