mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-16 19:41:06 +03:00
Clean up field initialization. Fixes #497
This commit is contained in:
parent
628e3bf001
commit
497da7fc69
|
@ -100,7 +100,8 @@ class BaseSerializer(Field):
|
|||
_options_class = SerializerOptions
|
||||
_dict_class = SortedDictWithMetadata # Set to unsorted dict for backwards compatibility with unsorted implementations.
|
||||
|
||||
def __init__(self, instance=None, data=None, files=None, context=None, partial=False, **kwargs):
|
||||
def __init__(self, instance=None, data=None, files=None,
|
||||
context=None, partial=False, **kwargs):
|
||||
super(BaseSerializer, self).__init__(**kwargs)
|
||||
self.opts = self._options_class(self.Meta)
|
||||
self.parent = None
|
||||
|
@ -151,8 +152,6 @@ class BaseSerializer(Field):
|
|||
base_fields = copy.deepcopy(self.base_fields)
|
||||
for key, field in base_fields.items():
|
||||
ret[key] = field
|
||||
# Set up the field
|
||||
field.initialize(parent=self, field_name=key)
|
||||
|
||||
# Add in the default fields
|
||||
default_fields = self.get_default_fields()
|
||||
|
@ -172,6 +171,10 @@ class BaseSerializer(Field):
|
|||
for key in self.opts.exclude:
|
||||
ret.pop(key, None)
|
||||
|
||||
# Initialize the fields
|
||||
for key, field in ret.items():
|
||||
field.initialize(parent=self, field_name=key)
|
||||
|
||||
return ret
|
||||
|
||||
#####
|
||||
|
@ -186,6 +189,13 @@ class BaseSerializer(Field):
|
|||
if parent.opts.depth:
|
||||
self.opts.depth = parent.opts.depth - 1
|
||||
|
||||
# We need to call initialize here to ensure any nested
|
||||
# serializers that will have already called initialize on their
|
||||
# descendants get updated with *their* parent.
|
||||
# We could be a bit more smart about this, but it'll do for now.
|
||||
for key, field in self.fields.items():
|
||||
field.initialize(parent=self, field_name=key)
|
||||
|
||||
#####
|
||||
# Methods to convert or revert from objects <--> primitive representations.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.test import TestCase
|
|||
from rest_framework import serializers
|
||||
from rest_framework.tests.models import (Album, ActionItem, Anchor, BasicModel,
|
||||
BlankFieldModel, BlogPost, Book, CallableDefaultValueModel, DefaultValueModel,
|
||||
ManyToManyModel, Person, ReadOnlyManyToManyModel)
|
||||
ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo)
|
||||
|
||||
|
||||
class SubComment(object):
|
||||
|
@ -764,3 +764,55 @@ class DepthTest(TestCase):
|
|||
'writer': {'id': 1, 'name': u'django', 'age': 1}}
|
||||
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
|
||||
class NestedSerializerContextTests(TestCase):
|
||||
|
||||
def test_nested_serializer_context(self):
|
||||
"""
|
||||
Regression for #497
|
||||
|
||||
https://github.com/tomchristie/django-rest-framework/issues/497
|
||||
"""
|
||||
class PhotoSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Photo
|
||||
fields = ("description", "callable")
|
||||
|
||||
callable = serializers.SerializerMethodField('_callable')
|
||||
|
||||
def _callable(self, instance):
|
||||
if not 'context_item' in self.context:
|
||||
raise RuntimeError("context isn't getting passed into 2nd level nested serializer")
|
||||
return "success"
|
||||
|
||||
class AlbumSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Album
|
||||
fields = ("photo_set", "callable")
|
||||
|
||||
photo_set = PhotoSerializer(source="photo_set")
|
||||
callable = serializers.SerializerMethodField("_callable")
|
||||
|
||||
def _callable(self, instance):
|
||||
if not 'context_item' in self.context:
|
||||
raise RuntimeError("context isn't getting passed into 1st level nested serializer")
|
||||
return "success"
|
||||
|
||||
class AlbumCollection(object):
|
||||
albums = None
|
||||
|
||||
class AlbumCollectionSerializer(serializers.Serializer):
|
||||
albums = AlbumSerializer(source="albums")
|
||||
|
||||
album1 = Album.objects.create(title="album 1")
|
||||
album2 = Album.objects.create(title="album 2")
|
||||
Photo.objects.create(description="Bigfoot", album=album1)
|
||||
Photo.objects.create(description="Unicorn", album=album1)
|
||||
Photo.objects.create(description="Yeti", album=album2)
|
||||
Photo.objects.create(description="Sasquatch", album=album2)
|
||||
album_collection = AlbumCollection()
|
||||
album_collection.albums = [album1, album2]
|
||||
|
||||
# This will raise RuntimeError if context doesn't get passed correctly to the nested Serializers
|
||||
AlbumCollectionSerializer(album_collection, context={'context_item': 'album context'}).data
|
||||
|
|
Loading…
Reference in New Issue
Block a user