Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed deferred loading of fields with default values.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10113 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5ac154e06568b9815e85b32f144ab4ee10190a61 1 parent 10923b4
@malcolmt malcolmt authored
View
14 django/db/models/base.py
@@ -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.
View
0  tests/regressiontests/defer_regress/__init__.py
No changes.
View
47 tests/regressiontests/defer_regress/models.py
@@ -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
+
+"""
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.