Opened 14 years ago
Closed 13 years ago
#13562 closed Bug (worksforme)
values() cannot follow reverse one-to-one relationship
Reported by: | Ben Davis | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.2 |
Severity: | Normal | Keywords: | |
Cc: | bendavis78@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This is similar to #7270, which fixed reverse-one-to-one when doing select_related, however this did not fix reverse-one-to-one when using values().
For example, given that you have a model "Place", and a model "Restaurant" which has a one-to-one relationship with "Place":
>>> Place.objects.all().values('name','restaurant__serves_hot_dogs') [{'name':'Some restaurant','restaurant__serves_hot_dogs':True},{'name':'Not a Restaurant','restaurant__serves_hot_dogs': None}]
Attachments (2)
Change History (13)
by , 14 years ago
Attachment: | values-reverse-one-to-one__test-only.diff added |
---|
comment:1 by , 14 years ago
Seems reasonable to me, but honest question: this is going to filter out all non-restaurant objs, why not just do Restaurant.objects.values("serves_hot_dogs", "name")
?
comment:2 by , 14 years ago
@Alex: I would argue that it should not filter out all non-restaurant objects; i.e., it should do a LEFT JOIN. The reasoning is that this is the same behavior when doing a .select_related(), and most people would expect all objects to be returned if the "Place" type since that is the base model of the queryset.
comment:4 by , 14 years ago
Cc: | added |
---|
Yes, if you do Place.objects.all().select_related('restaurant'), it performs a LEFT OUTER JOIN. I would argue that this is how it should happen. It seems much less intuitive that a .select_related() would alter the number of results returned.
comment:5 by , 14 years ago
I'm not talking about select_related() (it should of course never alter result set). i'm talking about Place.objects.values("some_nullable_fkey")
, we should be consistent with whatever behavior that has.
comment:6 by , 14 years ago
Alex, I'm a bit confused why you're asking about nullable foreign keys -- If Place had, eg, owner = ForeignKey(Owner,null=True,blank=True)
, and if we did Place.objects.values('owner')
, we'd get [{'owner': None}, {'owner': 1}]
. The reverse of that, of course, wouldn't make sense, since it's a many-to-one relationship.
Regardless, I would argue that in no case should .values() alter the number of rows returned in the result set. We expect the same of .select_related(), so I don't see why .values() should behave differently.
comment:8 by , 14 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:9 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:10 by , 13 years ago
Easy pickings: | unset |
---|---|
UI/UX: | unset |
I think this was fixed in 1.3: the docs say:
you can now also refer to fields on related models with reverse relations through OneToOneField, ForeignKey and ManyToManyField attributes
The patch no longer applies, but I've ported it quickly from doctest to unittest (see attachement) and the test passes.
by , 13 years ago
Attachment: | 13562_test_only.diff added |
---|
comment:11 by , 13 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
Closing since the problem appears to be fixed.
Patch for test that should pass.