#15787: select_related with nested fields affects query result
------------------------+---------------------------------------------
 Reporter:  kriomant@…  |         Owner:  nobody
     Type:  Bug         |        Status:  new
Milestone:              |     Component:  Database layer (models, ORM)
  Version:  1.3         |      Severity:  Normal
 Keywords:              |  Triage Stage:  Unreviewed
Has patch:  0           |
------------------------+---------------------------------------------
 I belive select_related should never affect query result, but only
 optimize referenced objects loading. However, I've found a case where
 query result is changed.

 === models.py ===
 {{{#!python
 from django.db import models

 class Thing(models.Model):
         name = models.CharField(max_length=255)

         def __unicode__(self):
                 return self.name

 class User(models.Model):
         login = models.CharField(max_length=255)

 class Lock(models.Model):
         description = models.CharField(max_length=255)

         # Only one lock per thing is allowed.
         thing = models.OneToOneField(Thing)

         user = models.ForeignKey(User)

 }}}

 === tests.py ===
 {{{#!python
 from django.test import TestCase

 from reproduce.models import *

 class SimpleTest(TestCase):
         def setUp(self):
                 user = User.objects.create(login='james')

                 # Unlocked thing.
                 self.unlocked_thing =
 Thing.objects.create(name='unlocked')

                 # Locked thing.
                 self.locked_thing = Thing.objects.create(name='locked')
                 Lock.objects.create(thing=self.locked_thing,
 description='lock', user=user)

         def test_simple_query(self):
                 things = Thing.objects.all()
                 self.assertEqual(set(things), set([self.unlocked_thing,
 self.locked_thing]))

         def test_select_related(self):
                 things = Thing.objects.select_related('lock')
                 self.assertEqual(set(things), set([self.locked_thing,
 self.unlocked_thing]))

         def test_deep_select_related(self):
                 things = Thing.objects.select_related('lock',
 'lock__user')
                 # This fails.
                 self.assertEqual(set(things), set([self.locked_thing,
 self.unlocked_thing]))
 }}}

 ''./manage.py test reproduce'' produces:

 {{{
 Creating test database for alias 'default'...
 F..
 ======================================================================
 FAIL: test_deep_select_related (reproduce.tests.SimpleTest)
 ----------------------------------------------------------------------
 Traceback (most recent call last):
   File "/home/.../select_related_bug/reproduce/tests.py", line 27, in
 test_deep_select_related
     self.assertEqual(set(things), set([self.locked_thing,
 self.unlocked_thing]))
 AssertionError: Items in the second set but not the first:
 <Thing: unlocked>

 ----------------------------------------------------------------------
 Ran 3 tests in 0.006s

 FAILED (failures=1)
 Destroying test database for alias 'default'...
 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/15787>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

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

Reply via email to