aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig de Stigter2013-10-11 15:31:55 +1300
committerCraig de Stigter2013-10-11 15:31:55 +1300
commit7c3769f04b5ec2cd14dcbd7e3601d59092255906 (patch)
treec665a95c57a5cee42ff06fa2b0fd8a68641e1cd2
parentf18158358d99f94e2475821b1f3477dde0731bd7 (diff)
downloaddjango-rest-framework-7c3769f04b5ec2cd14dcbd7e3601d59092255906.tar.bz2
fix writing into foreign key with non-null source
-rw-r--r--rest_framework/serializers.py2
-rw-r--r--rest_framework/tests/test_serializer_nested.py67
2 files changed, 68 insertions, 1 deletions
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 33db82ee..fa5ac143 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -403,7 +403,7 @@ class BaseSerializer(WritableField):
return
# Set the serializer object if it exists
- obj = getattr(self.parent.object, field_name) if self.parent.object else None
+ obj = get_component(self.parent.object, self.source or field_name) if self.parent.object else None
obj = obj.all() if is_simple_callable(getattr(obj, 'all', None)) else obj
if self.source == '*':
diff --git a/rest_framework/tests/test_serializer_nested.py b/rest_framework/tests/test_serializer_nested.py
index 71d0e24b..e454235a 100644
--- a/rest_framework/tests/test_serializer_nested.py
+++ b/rest_framework/tests/test_serializer_nested.py
@@ -244,3 +244,70 @@ class WritableNestedSerializerObjectTests(TestCase):
serializer = self.AlbumSerializer(data=data, many=True)
self.assertEqual(serializer.is_valid(), True)
self.assertEqual(serializer.object, expected_object)
+
+
+class ForeignKeyNestedSerializerUpdateTests(TestCase):
+ def setUp(self):
+ class Artist(object):
+ def __init__(self, name):
+ self.name = name
+
+ def __eq__(self, other):
+ return self.name == other.name
+
+ class Album(object):
+ def __init__(self, name, artist):
+ self.name, self.artist = name, artist
+
+ def __eq__(self, other):
+ return self.name == other.name and self.artist == other.artist
+
+ class ArtistSerializer(serializers.Serializer):
+ name = serializers.CharField()
+
+ def restore_object(self, attrs, instance=None):
+ if instance:
+ instance.name = attrs['name']
+ else:
+ instance = Artist(attrs['name'])
+ return instance
+
+ class AlbumSerializer(serializers.Serializer):
+ name = serializers.CharField()
+ by = ArtistSerializer(source='artist')
+
+ def restore_object(self, attrs, instance=None):
+ if instance:
+ instance.name = attrs['name']
+ instance.artist = attrs['artist']
+ else:
+ instance = Album(attrs['name'], attrs['artist'])
+ return instance
+
+ self.Artist = Artist
+ self.Album = Album
+ self.AlbumSerializer = AlbumSerializer
+
+ def test_create_via_foreign_key_with_source(self):
+ """
+ Check that we can both *create* and *update* into objects across
+ ForeignKeys that have a `source` specified.
+ Regression test for #<ticket>
+ """
+ data = {
+ 'name': 'Discovery',
+ 'by': {'name': 'Daft Punk'},
+ }
+
+ expected = self.Album(artist=self.Artist('Daft Punk'), name='Discovery')
+
+ # create
+ serializer = self.AlbumSerializer(data=data)
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(serializer.object, expected)
+
+ # update
+ original = self.Album(artist=self.Artist('The Bats'), name='Free All the Monsters')
+ serializer = self.AlbumSerializer(instance=original, data=data)
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(serializer.object, expected)