Filter via related_name in inherited model not working .. Bug?
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?
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?
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?
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.