Merge pull request #1527 from Ian-Foote/generic_foreign_key

Set GenericForeignKey fields on object before save
This commit is contained in:
Xavier Ordoquy 2014-04-16 11:27:06 +02:00
commit 1d404874b3
2 changed files with 29 additions and 10 deletions

View File

@ -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):
# 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,17 +955,15 @@ 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:
for key, val in attrs.items(): instance = self.opts.model()
try:
setattr(instance, key, val)
except ValueError:
self._errors[key] = self.error_messages['required']
# ...or create a new instance for key, val in attrs.items():
else: try:
instance = self.opts.model(**attrs) setattr(instance, key, val)
except ValueError:
self._errors[key] = self.error_messages['required']
# 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

View File

@ -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)