Set up serializer fields lazily on-demand.

This avoids AppRegistryNotReady problems in Django 1.7 with nested serializers,
which are instantiated at import time, possibly before Django's app registry is
fully populated.
This commit is contained in:
Carl Meyer 2014-10-16 12:16:13 -06:00
parent 34a7a48c1d
commit 140f8620ae
3 changed files with 11 additions and 4 deletions

View File

@ -22,6 +22,7 @@ from django.db import models
from django.forms import widgets
from django.utils import six
from django.utils.datastructures import SortedDict
from django.utils.functional import cached_property
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.settings import api_settings
@ -197,7 +198,6 @@ class BaseSerializer(WritableField):
self.init_data = data
self.init_files = files
self.object = instance
self.fields = self.get_fields()
self._data = None
self._files = None
@ -212,6 +212,10 @@ class BaseSerializer(WritableField):
#####
# Methods to determine which fields to use when (de)serializing objects.
@cached_property
def fields(self):
return self.get_fields()
def get_default_fields(self):
"""
Return the complete set of default fields for the object, as a dict.

View File

@ -102,7 +102,7 @@ class RelatedFieldSourceTests(TestCase):
self.assertEqual(value, ['BlogPost object'])
# Regression for #1129
def test_exception_for_incorect_fk(self):
def test_exception_for_incorrect_fk(self):
"""
Check that the exception message are correct if the source field
doesn't exist.
@ -123,8 +123,9 @@ class RelatedFieldSourceTests(TestCase):
(serializers.ModelSerializer,),
attrs
)
serializer = TestSerializer(data={'name': 'foo'})
with self.assertRaises(AttributeError):
TestSerializer(data={'name': 'foo'})
serializer.fields
@unittest.skipIf(get_version() < '1.6.0', 'Upstream behaviour changed in v1.6')

View File

@ -327,7 +327,9 @@ class BasicTests(TestCase):
"""
Regression test for #652.
"""
self.assertRaises(AssertionError, PersonSerializerInvalidReadOnly, [])
serializer = PersonSerializerInvalidReadOnly()
with self.assertRaises(AssertionError):
serializer.fields
def test_serializer_data_is_cleared_on_save(self):
"""