aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Ordoquy2014-04-16 11:27:06 +0200
committerXavier Ordoquy2014-04-16 11:27:06 +0200
commit1d404874b3f0f5b16f3b38ba322f31a18c41aad6 (patch)
treece492344b34baeb810cb3b2d09c4f72b37871b09
parent03b4c60b2db1652be448b15ce7abdf3154601b9d (diff)
parent853c7a16c15c7291561bc4b3dfbcad88ea262a18 (diff)
downloaddjango-rest-framework-1d404874b3f0f5b16f3b38ba322f31a18c41aad6.tar.bz2
Merge pull request #1527 from Ian-Foote/generic_foreign_key
Set GenericForeignKey fields on object before save
-rw-r--r--rest_framework/serializers.py21
-rw-r--r--rest_framework/tests/test_genericrelations.py18
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)