Filter via related_name in inherited model not working .. Bug?

2011-04-15 Thread robim42
Hi guys,

I used model inheritance quite a while and came across a problem which
I can not resolve and actually think is might be a bug in django
itself.
Because of the size of the project I'm working on it would be a waste
of space using the original models here ... so I simplified the
classes to reproduce the problem.

--- models.py code --- snip ---
from django.db import models

class Base(models.Model):
name = models.CharField(max_length=20)

def __unicode__(self):
return self.name

class Seller(Base):
childa = models.CharField(max_length=20)

def __unicode__(self):
return u'%s: %s' %(self.name, self.childa)

class Buyer(Base):
childb = models.CharField(max_length=20)
partner = models.ForeignKey(Base, related_name = 'buyer_partner',
blank = True, null = True)

def __unicode__(self):
return u'%s: %s, %s' %(self.name, self.childb, self.partner)

class Item(models.Model):
name = models.CharField(max_length=20)
owner = models.ForeignKey(Base, related_name='item_owner',
blank=True, null=True)

def __unicode__(self):
return u'%s: %s' %(self.name, self.owner)
--- snap ---

I'm using postgresql in the real application and the sqlite3 backend
on this example here, both behave the same.
To add some data I do the following on the python shell (python manage
shell):
--- snip ---
>>> from multi.models import Seller, Buyer, Item, Base
>>> seller = Seller(name='Seller1', childa='ChildA')
>>> seller.save()
>>> buyer = Buyer(name='Buyer1', childb='ChildB', partner=seller)
>>> buyer.save()
>>> item = Item(name='Nice Thing', owner = buyer)
>>> item.save()

--- snap ---

After this I do some query to verify that everything is in the
database (also on the shell):
--- snip ---
>>> from multi.models import Seller, Buyer, Item, Base
>>> Buyer.objects.all()

[]
>>> Seller.objects.all()

[]
>>> Item.objects.all()

[]
--- snap ---

So all necessary data is in the database ... now a few queries to get
data back out and assigned to some vars ... and finally to filter
queries ... the first one is working, the second one seems to bee
'broken' (gives no result = []) and I don't know why ...
--- snip ---
>>> from multi.models import Seller, Buyer, Item, Base
>>> s = Seller.objects.get(name='Seller1')
>>> b = Buyer.objects.get(name='Buyer1')
>>> s


>>> b


>>> Item.objects.filter(owner=b)

[]
>>> Item.objects.filter(owner__buyer_partner = s)

[]
--- snap ---

Could anyone point me to the right direction or give me an example how
it is supposed to work?

Regards

 Alex

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



Re: Filter via related_name in inherited model not working .. Bug?

2011-04-15 Thread Carl Meyer
Hi Alex,

On 04/15/2011 07:51 AM, robim42 wrote:
> --- models.py code --- snip ---
> from django.db import models
> 
> class Base(models.Model):
> name = models.CharField(max_length=20)
> 
> def __unicode__(self):
> return self.name
> 
> class Seller(Base):
> childa = models.CharField(max_length=20)
> 
> def __unicode__(self):
> return u'%s: %s' %(self.name, self.childa)
> 
> class Buyer(Base):
> childb = models.CharField(max_length=20)
> partner = models.ForeignKey(Base, related_name = 'buyer_partner',
> blank = True, null = True)
> 
> def __unicode__(self):
> return u'%s: %s, %s' %(self.name, self.childb, self.partner)
> 
> class Item(models.Model):
> name = models.CharField(max_length=20)
> owner = models.ForeignKey(Base, related_name='item_owner',
> blank=True, null=True)
> 
> def __unicode__(self):
> return u'%s: %s' %(self.name, self.owner)
> --- snap ---
> 
> I'm using postgresql in the real application and the sqlite3 backend
> on this example here, both behave the same.
> To add some data I do the following on the python shell (python manage
> shell):
> --- snip ---
 from multi.models import Seller, Buyer, Item, Base
 seller = Seller(name='Seller1', childa='ChildA')
 seller.save()
 buyer = Buyer(name='Buyer1', childb='ChildB', partner=seller)
 buyer.save()
 item = Item(name='Nice Thing', owner = buyer)
 item.save()
> 
> --- snap ---
> 
> After this I do some query to verify that everything is in the
> database (also on the shell):
> --- snip ---
 from multi.models import Seller, Buyer, Item, Base
 Buyer.objects.all()
> 
> []
 Seller.objects.all()
> 
> []
 Item.objects.all()
> 
> []
> --- snap ---
> 
> So all necessary data is in the database ... now a few queries to get
> data back out and assigned to some vars ... and finally to filter
> queries ... the first one is working, the second one seems to bee
> 'broken' (gives no result = []) and I don't know why ...
> --- snip ---
 from multi.models import Seller, Buyer, Item, Base
 s = Seller.objects.get(name='Seller1')
 b = Buyer.objects.get(name='Buyer1')
 s
> 
> 
 b
> 
> 
 Item.objects.filter(owner=b)
> 
> []
 Item.objects.filter(owner__buyer_partner = s)
> 
> []
> --- snap ---
> 
> Could anyone point me to the right direction or give me an example how
> it is supposed to work?

If I'm reading this right, I think you're misunderstanding which side of
the relationship related_name applies to. The way you have your models
set up, "buyer_partner" is the name you would use to traverse from the
partner targeted by the "partner" FK back to the Buyer containing that
FK. To traverse from the Buyer to its partner, you would just use
"partner" (the name of the FK) not "buyer_partner" (the related_name).

The owner of your Item is your Buyer, so trying to filter by
owner__buyer_partner is using the wrong name; I would expect
owner__partner=s to work.

If the Item was owned by the Seller in this example, then I would expect
a filter on owner__buyer_partner=b to return the item.

Carl

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



Re: Filter via related_name in inherited model not working .. Bug?

2011-04-18 Thread robim42
Hi Carl,

thank you for your answer. I also thought that owner_partner should
work ... but when you try you get this:

>>> from multi.models import Seller, Buyer, Item, Base
>>> s = Seller.objects.get(name='Seller1')
>>> b = Buyer.objects.get(name='Buyer1')
>>> Item.objects.filter(owner__partner=s)
Traceback (most recent call last):
  File "", line 1, in 
  File "/Users/alex/alex/django-1.2.x/django/db/models/manager.py",
line 141, in filter
return self.get_query_set().filter(*args, **kwargs)
  File "/Users/alex/alex/django-1.2.x/django/db/models/query.py", line
561, in filter
return self._filter_or_exclude(False, *args, **kwargs)
  File "/Users/alex/alex/django-1.2.x/django/db/models/query.py", line
579, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
  File "/Users/alex/alex/django-1.2.x/django/db/models/sql/query.py",
line 1170, in add_q
can_reuse=used_aliases, force_having=force_having)
  File "/Users/alex/alex/django-1.2.x/django/db/models/sql/query.py",
line 1058, in add_filter
negate=negate, process_extras=process_extras)
  File "/Users/alex/alex/django-1.2.x/django/db/models/sql/query.py",
line 1237, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'partner' into field. Choices are:
buyer, buyer_partner, id, item_owner, name, seller

Which lead me to the conclusion that I have to use buyer_partner (the
related name) to get what I want (which is: all Items which habe been
bought by any buyer having partner s as a partner).

If I do a print query on the original filter, I get the following,
which seems not right to me:

>>> print Item.objects.filter(owner__buyer_partner = s).query
SELECT "multi_item"."id", "multi_item"."name", "multi_item"."owner_id"
FROM "multi_item" INNER JOIN "multi_base" ON ("multi_item"."owner_id"
= "multi_base"."id") INNER JOIN "multi_buyer" ON ("multi_base"."id" =
"multi_buyer"."partner_id") WHERE "multi_buyer"."base_ptr_id" = 2


Regards

Alex

On Apr 15, 5:01 pm, Carl Meyer  wrote:
> Hi Alex,
>
> On 04/15/2011 07:51 AM, robim42 wrote:
>
>
> > --- models.py code --- snip ---
> > from django.db import models
>
> > class Base(models.Model):
> >     name = models.CharField(max_length=20)
>
> >     def __unicode__(self):
> >         return self.name
>
> > class Seller(Base):
> >     childa = models.CharField(max_length=20)
>
> >     def __unicode__(self):
> >         return u'%s: %s' %(self.name, self.childa)
>
> > class Buyer(Base):
> >     childb = models.CharField(max_length=20)
> >     partner = models.ForeignKey(Base, related_name = 'buyer_partner',
> > blank = True, null = True)
>
> >     def __unicode__(self):
> >         return u'%s: %s, %s' %(self.name, self.childb, self.partner)
>
> > class Item(models.Model):
> >     name = models.CharField(max_length=20)
> >     owner = models.ForeignKey(Base, related_name='item_owner',
> > blank=True, null=True)
>
> >     def __unicode__(self):
> >         return u'%s: %s' %(self.name, self.owner)
> > --- snap ---
>
> > I'm using postgresql in the real application and the sqlite3 backend
> > on this example here, both behave the same.
> > To add some data I do the following on the python shell (python manage
> > shell):
> > --- snip ---
>  from multi.models import Seller, Buyer, Item, Base
>  seller = Seller(name='Seller1', childa='ChildA')
>  seller.save()
>  buyer = Buyer(name='Buyer1', childb='ChildB', partner=seller)
>  buyer.save()
>  item = Item(name='Nice Thing', owner = buyer)
>  item.save()
>
> > --- snap ---
>
> > After this I do some query to verify that everything is in the
> > database (also on the shell):
> > --- snip ---
>  from multi.models import Seller, Buyer, Item, Base
>  Buyer.objects.all()
>
> > []
>  Seller.objects.all()
>
> > []
>  Item.objects.all()
>
> > []
> > --- snap ---
>
> > So all necessary data is in the database ... now a few queries to get
> > data back out and assigned to some vars ... and finally to filter
> > queries ... the first one is working, the second one seems to bee
> > 'broken' (gives no result = []) and I don't know why ...
> > --- snip ---
>  from multi.models import Seller, Buyer, Item, Base
>  s = Seller.objects.get(name='Seller1')
>  b = Buyer.objects.get(name='Buyer1')
>  s
>
> > 
>  b
>
> > 
>  Item.objects.filter(owner=b)
>
> > []
>  Item.objects.filter(owner__buyer_partner = s)
>
> > []
> > --- snap ---
>
> > Could anyone point me to the right direction or give me an example how
> > it is supposed to work?
>
> If I'm reading this right, I think you're misunderstanding which side of
> the relationship related_name applies to. The way you have your models
> set up, "buyer_partner" is the name you would use to traverse from the
> partner targeted by the "partner" FK back to the Buyer containing that
> FK. To traverse from the Buyer to its partner, you would just use
> "partner" (the name of the FK) not "buyer_partner" (the re

Re: Filter via related_name in inherited model not working .. Bug?

2011-04-18 Thread Carl Meyer
Hi Alex,

On 04/18/2011 02:44 AM, robim42 wrote:
> thank you for your answer. I also thought that owner_partner should
> work ... but when you try you get this:

Sorry, not owner__partner - since partner is only a field on Buyer, not
on Base, you'd need owner__buyer__partner.

In any case, I don't see any evidence of a bug in Django here (we've got
a pretty good test suite for filter traversal and inheritance), so this
thread should move to django-users.

Carl

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