Skip to content

Commit

Permalink
Fixed deferred loading of fields with default values.
Browse files Browse the repository at this point in the history
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10113 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Mar 22, 2009
1 parent 10923b4 commit 5ac154e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
14 changes: 7 additions & 7 deletions django/db/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,14 @@ def __init__(self, *args, **kwargs):

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.
Expand Down
Empty file.
47 changes: 47 additions & 0 deletions tests/regressiontests/defer_regress/models.py
Original file line number Diff line number Diff line change
@@ -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
"""
}

0 comments on commit 5ac154e

Please sign in to comment.