mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-09 08:00:52 +03:00
Merge pull request #1527 from Ian-Foote/generic_foreign_key
Set GenericForeignKey fields on object before save
This commit is contained in:
commit
1d404874b3
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user