Fixed deferred loading of fields with default values.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10113 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
10923b42b3
commit
5ac154e065
|
@ -272,14 +272,14 @@ class Model(object):
|
|||
|
||||
for field in fields_iter:
|
||||
is_related_object = False
|
||||
# This slightly odd construct is so that we can access any
|
||||
# data-descriptor object (DeferredAttribute) without triggering its
|
||||
# __get__ method.
|
||||
if (field.attname not in kwargs and
|
||||
isinstance(self.__class__.__dict__.get(field.attname), DeferredAttribute)):
|
||||
# This field will be populated on request.
|
||||
continue
|
||||
if kwargs:
|
||||
# This slightly odd construct is so that we can access any
|
||||
# data-descriptor object (DeferredAttribute) without triggering
|
||||
# its __get__ method.
|
||||
if (field.attname not in kwargs and
|
||||
isinstance(self.__class__.__dict__.get(field.attname), DeferredAttribute)):
|
||||
# This field will be populated on request.
|
||||
continue
|
||||
if isinstance(field.rel, ManyToOneRel):
|
||||
try:
|
||||
# Assume object instance was passed in.
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
"""
|
||||
Regression tests for defer() / only() behavior.
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import connection, models
|
||||
|
||||
class Item(models.Model):
|
||||
name = models.CharField(max_length=10)
|
||||
text = models.TextField(default="xyzzy")
|
||||
value = models.IntegerField()
|
||||
other_value = models.IntegerField(default=0)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
__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__.
|
||||
|
||||
>>> settings.DEBUG = True
|
||||
>>> _ = Item.objects.create(name="first", value=42)
|
||||
>>> obj = Item.objects.only("name", "other_value").get(name="first")
|
||||
|
||||
# Accessing "name" doesn't trigger a new database query. Accessing "value" or
|
||||
# "text" should.
|
||||
>>> num = len(connection.queries)
|
||||
>>> obj.name
|
||||
u"first"
|
||||
>>> obj.other_value
|
||||
0
|
||||
>>> len(connection.queries) == num
|
||||
True
|
||||
>>> obj.value
|
||||
42
|
||||
>>> len(connection.queries) == num + 1 # Effect of values lookup.
|
||||
True
|
||||
>>> obj.text
|
||||
u"xyzzy"
|
||||
>>> len(connection.queries) == num + 2 # Effect of text lookup.
|
||||
True
|
||||
|
||||
>>> settings.DEBUG = False
|
||||
|
||||
"""
|
||||
}
|
||||
|
Loading…
Reference in New Issue