diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
index 8e804ec..9129d95 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -183,11 +183,29 @@ class DeferredAttribute(object):
         Retrieves and caches the value from the datastore on the first lookup.
         Returns the cached value.
         """
+        from django.db.models.fields import FieldDoesNotExist
+
         assert instance is not None
         cls = self.model_ref()
         data = instance.__dict__
         if data.get(self.field_name, self) is self:
-            data[self.field_name] = cls._base_manager.filter(pk=instance.pk).values_list(self.field_name, flat=True).using(instance._state.db).get()
+            # self.field_name is the attname of the field, but only() takes the
+            # actual name, so we need to translate it here.
+            try:
+                cls._meta.get_field_by_name(self.field_name)
+                name = self.field_name
+            except FieldDoesNotExist:
+                name = [f.name for f in cls._meta.fields
+                    if f.attname == self.field_name][0]
+            # We use only() instead of values() here because we want the
+            # various data coersion methods (to_python(), etc.) to be called
+            # here.
+            val = getattr(
+                cls._base_manager.filter(pk=instance.pk).only(name).using(
+                    instance._state.db).get(),
+                self.field_name
+            )
+            data[self.field_name] = val
         return data[self.field_name]
 
     def __set__(self, instance, value):
diff --git a/tests/modeltests/field_subclassing/fields.py b/tests/modeltests/field_subclassing/fields.py
new file mode 100644
index 0000000..d545b19
--- /dev/null
+++ b/tests/modeltests/field_subclassing/fields.py
@@ -0,0 +1,71 @@
+from django.core.exceptions import FieldError
+from django.db import models
+from django.utils import simplejson as json
+from django.utils.encoding import force_unicode
+
+
+class Small(object):
+    """
+    A simple class to show that non-trivial Python objects can be used as
+    attributes.
+    """
+    def __init__(self, first, second):
+        self.first, self.second = first, second
+
+    def __unicode__(self):
+        return u'%s%s' % (force_unicode(self.first), force_unicode(self.second))
+
+    def __str__(self):
+        return unicode(self).encode('utf-8')
+
+class SmallField(models.Field):
+    """
+    Turns the "Small" class into a Django field. Because of the similarities
+    with normal character fields and the fact that Small.__unicode__ does
+    something sensible, we don't need to implement a lot here.
+    """
+    __metaclass__ = models.SubfieldBase
+
+    def __init__(self, *args, **kwargs):
+        kwargs['max_length'] = 2
+        super(SmallField, self).__init__(*args, **kwargs)
+
+    def get_internal_type(self):
+        return 'CharField'
+
+    def to_python(self, value):
+        if isinstance(value, Small):
+            return value
+        return Small(value[0], value[1])
+
+    def get_db_prep_save(self, value):
+        return unicode(value)
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        if lookup_type == 'exact':
+            return force_unicode(value)
+        if lookup_type == 'in':
+            return [force_unicode(v) for v in value]
+        if lookup_type == 'isnull':
+            return []
+        raise FieldError('Invalid lookup type: %r' % lookup_type)
+
+
+class JSONField(models.TextField):
+    __metaclass__ = models.SubfieldBase
+    
+    description = ("JSONField automatically serializes and desializes values to "
+        "and from JSON.")
+    
+    def to_python(self, value):
+        if not value:
+            return None
+        
+        if isinstance(value, basestring):
+            value = json.loads(value)
+        return value
+    
+    def get_db_prep_save(self, value):
+        if value is None:
+            return None
+        return json.dumps(value)
diff --git a/tests/modeltests/field_subclassing/models.py b/tests/modeltests/field_subclassing/models.py
index c776146..93b30c2 100644
--- a/tests/modeltests/field_subclassing/models.py
+++ b/tests/modeltests/field_subclassing/models.py
@@ -2,56 +2,12 @@
 Tests for field subclassing.
 """
 
+from django.core import serializers
 from django.db import models
 from django.utils.encoding import force_unicode
-from django.core import serializers
-from django.core.exceptions import FieldError
-
-class Small(object):
-    """
-    A simple class to show that non-trivial Python objects can be used as
-    attributes.
-    """
-    def __init__(self, first, second):
-        self.first, self.second = first, second
-
-    def __unicode__(self):
-        return u'%s%s' % (force_unicode(self.first), force_unicode(self.second))
-
-    def __str__(self):
-        return unicode(self).encode('utf-8')
 
-class SmallField(models.Field):
-    """
-    Turns the "Small" class into a Django field. Because of the similarities
-    with normal character fields and the fact that Small.__unicode__ does
-    something sensible, we don't need to implement a lot here.
-    """
-    __metaclass__ = models.SubfieldBase
+from fields import Small, SmallField, JSONField
 
-    def __init__(self, *args, **kwargs):
-        kwargs['max_length'] = 2
-        super(SmallField, self).__init__(*args, **kwargs)
-
-    def get_internal_type(self):
-        return 'CharField'
-
-    def to_python(self, value):
-        if isinstance(value, Small):
-            return value
-        return Small(value[0], value[1])
-
-    def get_db_prep_save(self, value):
-        return unicode(value)
-
-    def get_db_prep_lookup(self, lookup_type, value):
-        if lookup_type == 'exact':
-            return force_unicode(value)
-        if lookup_type == 'in':
-            return [force_unicode(v) for v in value]
-        if lookup_type == 'isnull':
-            return []
-        raise FieldError('Invalid lookup type: %r' % lookup_type)
 
 class MyModel(models.Model):
     name = models.CharField(max_length=10)
@@ -60,6 +16,9 @@ class MyModel(models.Model):
     def __unicode__(self):
         return force_unicode(self.name)
 
+class DataModel(models.Model):
+    data = JSONField()
+
 __test__ = {'API_TESTS': ur"""
 # Creating a model with custom fields is done as per normal.
 >>> s = Small(1, 2)
diff --git a/tests/modeltests/field_subclassing/tests.py b/tests/modeltests/field_subclassing/tests.py
new file mode 100644
index 0000000..731ab51
--- /dev/null
+++ b/tests/modeltests/field_subclassing/tests.py
@@ -0,0 +1,21 @@
+from django.test import TestCase
+
+from models import DataModel
+
+
+class CustomField(TestCase):
+    def test_defer(self):
+        d = DataModel.objects.create(data=[1, 2, 3])
+        
+        self.assertTrue(isinstance(d.data, list))
+        
+        d = DataModel.objects.get(pk=d.pk)
+        self.assertTrue(isinstance(d.data, list))
+        self.assertEqual(d.data, [1, 2, 3])
+        
+        d = DataModel.objects.defer("data").get(pk=d.pk)
+        d.save()
+        
+        d = DataModel.objects.get(pk=d.pk)
+        self.assertTrue(isinstance(d.data, list))
+        self.assertEqual(d.data, [1, 2, 3])
diff --git a/tests/regressiontests/defer_regress/models.py b/tests/regressiontests/defer_regress/models.py
index c32f5bb..08c4d62 100644
--- a/tests/regressiontests/defer_regress/models.py
+++ b/tests/regressiontests/defer_regress/models.py
@@ -142,8 +142,7 @@ False
 [<class 'regressiontests.defer_regress.models.Child'>, <class 'regressiontests.defer_regress.models.Item'>, <class 'regressiontests.defer_regress.models.Leaf'>, <class 'regressiontests.defer_regress.models.RelatedItem'>, <class 'regressiontests.defer_regress.models.ResolveThis'>]
 
 >>> sorted(get_models(models.get_app('defer_regress'), include_deferred=True), key=lambda obj: obj._meta.object_name)
-[<class 'regressiontests.defer_regress.models.Child'>, <class 'regressiontests.defer_regress.models.Item'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name_other_value_text'>, <class 'regressiontests.defer_regress.models.Item_Deferred_other_value_text_value'>, <class 'regressiontests.defer_regress.models.Item_Deferred_text_value'>, <class 'regressiontests.defer_regress.models.Leaf'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_name_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_second_child_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_value'>, <class 'regressiontests.defer_regress.models.RelatedItem'>, <class 'regressiontests.defer_regress.models.RelatedItem_Deferred_item_id'>, <class 'regressiontests.defer_regress.models.ResolveThis'>, <class 'regressiontests.defer_regress.models.ResolveThis_Deferred_num'>]
-
+[<class 'regressiontests.defer_regress.models.Child'>, <class 'regressiontests.defer_regress.models.Item'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name_other_value_text'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name_other_value_value'>, <class 'regressiontests.defer_regress.models.Item_Deferred_other_value_text_value'>, <class 'regressiontests.defer_regress.models.Item_Deferred_text_value'>, <class 'regressiontests.defer_regress.models.Leaf'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_child_id_second_child_id_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_name_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_second_child_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_value'>, <class 'regressiontests.defer_regress.models.RelatedItem'>, <class 'regressiontests.defer_regress.models.RelatedItem_Deferred_'>, <class 'regressiontests.defer_regress.models.RelatedItem_Deferred_item_id'>, <class 'regressiontests.defer_regress.models.ResolveThis'>, <class 'regressiontests.defer_regress.models.ResolveThis_Deferred_num'>]
 """
 }
 
