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.forms import widgets
from django.utils import six from django.utils import six
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.functional import cached_property
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
@ -197,7 +198,6 @@ class BaseSerializer(WritableField):
self.init_data = data self.init_data = data
self.init_files = files self.init_files = files
self.object = instance self.object = instance
self.fields = self.get_fields()
self._data = None self._data = None
self._files = None self._files = None
@ -212,6 +212,10 @@ class BaseSerializer(WritableField):
##### #####
# Methods to determine which fields to use when (de)serializing objects. # 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): def get_default_fields(self):
""" """
Return the complete set of default fields for the object, as a dict. 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']) self.assertEqual(value, ['BlogPost object'])
# Regression for #1129 # 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 Check that the exception message are correct if the source field
doesn't exist. doesn't exist.
@ -123,8 +123,9 @@ class RelatedFieldSourceTests(TestCase):
(serializers.ModelSerializer,), (serializers.ModelSerializer,),
attrs attrs
) )
serializer = TestSerializer(data={'name': 'foo'})
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
TestSerializer(data={'name': 'foo'}) serializer.fields
@unittest.skipIf(get_version() < '1.6.0', 'Upstream behaviour changed in v1.6') @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. 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): def test_serializer_data_is_cleared_on_save(self):
""" """