Commit 1d404874 by Xavier Ordoquy

Merge pull request #1527 from Ian-Foote/generic_foreign_key

Set GenericForeignKey fields on object before save
parents 03b4c60b 853c7a16
...@@ -16,6 +16,7 @@ import datetime ...@@ -16,6 +16,7 @@ import datetime
import inspect import inspect
import types import types
from decimal import Decimal from decimal import Decimal
from django.contrib.contenttypes.generic import GenericForeignKey
from django.core.paginator import Page from django.core.paginator import Page
from django.db import models from django.db import models
from django.forms import widgets from django.forms import widgets
...@@ -943,6 +944,8 @@ class ModelSerializer(Serializer): ...@@ -943,6 +944,8 @@ class ModelSerializer(Serializer):
# Forward m2m relations # Forward m2m relations
for field in meta.many_to_many + meta.virtual_fields: for field in meta.many_to_many + meta.virtual_fields:
if isinstance(field, GenericForeignKey):
continue
if field.name in attrs: if field.name in attrs:
m2m_data[field.name] = attrs.pop(field.name) m2m_data[field.name] = attrs.pop(field.name)
...@@ -952,18 +955,16 @@ class ModelSerializer(Serializer): ...@@ -952,18 +955,16 @@ class ModelSerializer(Serializer):
if isinstance(self.fields.get(field_name, None), Serializer): if isinstance(self.fields.get(field_name, None), Serializer):
nested_forward_relations[field_name] = attrs[field_name] nested_forward_relations[field_name] = attrs[field_name]
# Update an existing instance... # Create an empty instance of the model
if instance is not None: if instance is None:
instance = self.opts.model()
for key, val in attrs.items(): for key, val in attrs.items():
try: try:
setattr(instance, key, val) setattr(instance, key, val)
except ValueError: except ValueError:
self._errors[key] = self.error_messages['required'] self._errors[key] = self.error_messages['required']
# ...or create a new instance
else:
instance = self.opts.model(**attrs)
# Any relations that cannot be set until we've # Any relations that cannot be set until we've
# saved the model get hidden away on these # saved the model get hidden away on these
# private attributes, so we can deal with them # private attributes, so we can deal with them
......
...@@ -131,3 +131,21 @@ class TestGenericRelations(TestCase): ...@@ -131,3 +131,21 @@ class TestGenericRelations(TestCase):
} }
] ]
self.assertEqual(serializer.data, expected) 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)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment