diff options
| author | Craig de Stigter | 2013-10-11 15:31:55 +1300 | 
|---|---|---|
| committer | Craig de Stigter | 2013-10-11 15:31:55 +1300 | 
| commit | 7c3769f04b5ec2cd14dcbd7e3601d59092255906 (patch) | |
| tree | c665a95c57a5cee42ff06fa2b0fd8a68641e1cd2 | |
| parent | f18158358d99f94e2475821b1f3477dde0731bd7 (diff) | |
| download | django-rest-framework-7c3769f04b5ec2cd14dcbd7e3601d59092255906.tar.bz2 | |
fix writing into foreign key with non-null source
| -rw-r--r-- | rest_framework/serializers.py | 2 | ||||
| -rw-r--r-- | rest_framework/tests/test_serializer_nested.py | 67 | 
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) | 
