#21240 closed Bug (fixed)
Breaking change regarding select_related+OneToOneField missing from release notes
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Documentation | Version: | 1.5 |
Severity: | Normal | Keywords: | breaking change |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Django 1.5 made changes to the way select_related interacts with OneToOneField reverse relations: https://code.djangoproject.com/ticket/13839
This is a breaking change and was not included in the release notes.
The behaviour of this interaction was previously undocumented (and had an open bug), but since it is core ORM functionality, I don't think you can fault people for relying on it.
Please document it in 1.5's release notes, preferably with its own paragraph.
Change History (9)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Models:
class Nut (models.Model): pass class Bolt (models.Model): nut = models.OneToOneField (Nut)
Relevant tests:
class FindingOrphanedNutsTestcase (TestCase): def test_old_behaviour__will_fail_on_1_5_and_later (self): # fails by letting DoesNotExist escape nut = Nut.objects.create () nuts = [nut for nut in Nut.objects.all().select_related("bolt") if nut.bolt is None] self.assertListEqual (nuts, [nut]) def test_new_behaviour__will_fail_on_1_4_and_earlier (self): # fails by producing an empty list nut = Nut.objects.create () nuts = [] for nut in Nut.objects.all().select_related("bolt"): try: nut.bolt except Bolt.DoesNotExist: nuts.append (nut) self.assertListEqual (nuts, [nut])
Now of course you could write that to accommodate both None and DoesNotExist (or just with a .filter), but that's not the point, it's the fact that old code for many years and releases had to handle None, but didn't have to handle DoesNotExist. And with 1.5 it suddenly has to handle DoesNotExist and can disregard None.
comment:3 by , 11 years ago
I just realized I made a serious faux pas in the testcase when pasting code around (inadvertently re-using the local "nut"), it still works fine though. If someone could edit and change the loop variable name, that'd be lovely, wouldn't want to clutter the ticket with another half-a-screen of nearly identical code.
comment:4 by , 11 years ago
Triage Stage: | Unreviewed → Accepted |
---|
A quick mention in backwards incompatible changes seems OK to me. Miscellaneous is probably the right place.
comment:5 by , 11 years ago
marcin, could you propose text for this that you would have found helpful? I'm not sure how to describe it.
comment:6 by , 11 years ago
How about "Accessing reverse one-to-one relations fetched via select_related now raises DoesNotExist instead of returning None."
comment:7 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Could you add an example of what breaks and how? This should include example models, query and how the query behaves in 1.4 compared to 1.5.