Fixed #10695 -- Fixed implementation of deferred attribute retrieval.

The original implementation had a few silly bugs in it that meant that data was
not being used only on the instance of the class that it was appropriate for
(one of the traps when using class-level things). No more!

Thanks to Justin Bronn and Alex Gaynor for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10382 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2009-04-04 03:21:31 +00:00
parent 19d1450929
commit dded5f52cc
5 changed files with 63 additions and 45 deletions

View file

@ -6,7 +6,7 @@ from django.conf import settings
from django.db import connection, models
class Item(models.Model):
name = models.CharField(max_length=10)
name = models.CharField(max_length=15)
text = models.TextField(default="xyzzy")
value = models.IntegerField()
other_value = models.IntegerField(default=0)
@ -14,6 +14,9 @@ class Item(models.Model):
def __unicode__(self):
return self.name
class RelatedItem(models.Model):
item = models.ForeignKey(Item)
__test__ = {"regression_tests": """
Deferred fields should really be deferred and not accidentally use the field's
default value just because they aren't passed to __init__.
@ -39,9 +42,31 @@ True
u"xyzzy"
>>> len(connection.queries) == num + 2 # Effect of text lookup.
True
>>> obj.text
u"xyzzy"
>>> len(connection.queries) == num + 2
True
>>> settings.DEBUG = False
Regression test for #10695. Make sure different instances don't inadvertently
share data in the deferred descriptor objects.
>>> i = Item.objects.create(name="no I'm first", value=37)
>>> items = Item.objects.only('value').order_by('-value')
>>> items[0].name
u'first'
>>> items[1].name
u"no I'm first"
>>> _ = RelatedItem.objects.create(item=i)
>>> r = RelatedItem.objects.defer('item').get()
>>> r.item_id == i.id
True
>>> r.item == i
True
"""
}