diff options
| -rw-r--r-- | rest_framework/serializers.py | 21 | ||||
| -rw-r--r-- | rest_framework/tests/test_genericrelations.py | 18 | 
2 files changed, 29 insertions, 10 deletions
| diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index cb7539e0..ea9509bf 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -16,6 +16,7 @@ import datetime  import inspect  import types  from decimal import Decimal +from django.contrib.contenttypes.generic import GenericForeignKey  from django.core.paginator import Page  from django.db import models  from django.forms import widgets @@ -943,6 +944,8 @@ class ModelSerializer(Serializer):          # Forward m2m relations          for field in meta.many_to_many + meta.virtual_fields: +            if isinstance(field, GenericForeignKey): +                continue              if field.name in attrs:                  m2m_data[field.name] = attrs.pop(field.name) @@ -952,17 +955,15 @@ class ModelSerializer(Serializer):              if isinstance(self.fields.get(field_name, None), Serializer):                  nested_forward_relations[field_name] = attrs[field_name] -        # Update an existing instance... -        if instance is not None: -            for key, val in attrs.items(): -                try: -                    setattr(instance, key, val) -                except ValueError: -                    self._errors[key] = self.error_messages['required'] +        # Create an empty instance of the model +        if instance is None: +            instance = self.opts.model() -        # ...or create a new instance -        else: -            instance = self.opts.model(**attrs) +        for key, val in attrs.items(): +            try: +                setattr(instance, key, val) +            except ValueError: +                self._errors[key] = self.error_messages['required']          # Any relations that cannot be set until we've          # saved the model get hidden away on these diff --git a/rest_framework/tests/test_genericrelations.py b/rest_framework/tests/test_genericrelations.py index fa09c9e6..46a2d863 100644 --- a/rest_framework/tests/test_genericrelations.py +++ b/rest_framework/tests/test_genericrelations.py @@ -131,3 +131,21 @@ class TestGenericRelations(TestCase):          }          ]          self.assertEqual(serializer.data, expected) + +    def test_restore_object_generic_fk(self): +        """ +        Ensure an object with a generic foreign key can be restored. +        """ + +        class TagSerializer(serializers.ModelSerializer): +            class Meta: +                model = Tag +                exclude = ('content_type', 'object_id') + +        serializer = TagSerializer() + +        bookmark = Bookmark(url='http://example.com') +        attrs = {'tagged_item': bookmark, 'tag': 'example'} + +        tag = serializer.restore_object(attrs) +        self.assertEqual(tag.tagged_item, bookmark) | 
