mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-09 08:00:52 +03:00
Support reverse FK creation
This commit is contained in:
commit
caaf1c80f5
|
@ -496,19 +496,26 @@ class ModelSerializer(Serializer):
|
||||||
Restore the model instance.
|
Restore the model instance.
|
||||||
"""
|
"""
|
||||||
self.m2m_data = {}
|
self.m2m_data = {}
|
||||||
|
self.related_data = {}
|
||||||
|
|
||||||
if instance is not None:
|
if instance is not None:
|
||||||
for key, val in attrs.items():
|
for key, val in attrs.items():
|
||||||
setattr(instance, key, val)
|
setattr(instance, key, val)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Reverse relations
|
# Reverse fk relations
|
||||||
|
for (obj, model) in self.opts.model._meta.get_all_related_objects_with_model():
|
||||||
|
field_name = obj.field.related_query_name()
|
||||||
|
if field_name in attrs:
|
||||||
|
self.related_data[field_name] = attrs.pop(field_name)
|
||||||
|
|
||||||
|
# Reverse m2m relations
|
||||||
for (obj, model) in self.opts.model._meta.get_all_related_m2m_objects_with_model():
|
for (obj, model) in self.opts.model._meta.get_all_related_m2m_objects_with_model():
|
||||||
field_name = obj.field.related_query_name()
|
field_name = obj.field.related_query_name()
|
||||||
if field_name in attrs:
|
if field_name in attrs:
|
||||||
self.m2m_data[field_name] = attrs.pop(field_name)
|
self.m2m_data[field_name] = attrs.pop(field_name)
|
||||||
|
|
||||||
# Forward relations
|
# Forward m2m relations
|
||||||
for field in self.opts.model._meta.many_to_many:
|
for field in self.opts.model._meta.many_to_many:
|
||||||
if field.name in attrs:
|
if field.name in attrs:
|
||||||
self.m2m_data[field.name] = attrs.pop(field.name)
|
self.m2m_data[field.name] = attrs.pop(field.name)
|
||||||
|
@ -534,6 +541,11 @@ class ModelSerializer(Serializer):
|
||||||
setattr(self.object, accessor_name, object_list)
|
setattr(self.object, accessor_name, object_list)
|
||||||
self.m2m_data = {}
|
self.m2m_data = {}
|
||||||
|
|
||||||
|
if getattr(self, 'related_data', None):
|
||||||
|
for accessor_name, object_list in self.related_data.items():
|
||||||
|
setattr(self.object, accessor_name, object_list)
|
||||||
|
self.related_data = {}
|
||||||
|
|
||||||
return self.object
|
return self.object
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class ForeignKeySource(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class ForeignKeyTargetSerializer(serializers.ModelSerializer):
|
class ForeignKeyTargetSerializer(serializers.ModelSerializer):
|
||||||
sources = serializers.ManyPrimaryKeyRelatedField(read_only=True)
|
sources = serializers.ManyPrimaryKeyRelatedField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ForeignKeyTarget
|
model = ForeignKeyTarget
|
||||||
|
@ -235,24 +235,23 @@ class PKForeignKeyTests(TestCase):
|
||||||
]
|
]
|
||||||
self.assertEquals(serializer.data, expected)
|
self.assertEquals(serializer.data, expected)
|
||||||
|
|
||||||
# TODO: See #511
|
def test_reverse_foreign_key_create(self):
|
||||||
# def test_reverse_foreign_key_create(self):
|
data = {'id': 3, 'name': u'target-3', 'sources': [1, 3]}
|
||||||
# data = {'id': 3, 'name': u'target-3', 'sources': [1, 3]}
|
serializer = ForeignKeyTargetSerializer(data=data)
|
||||||
# serializer = ForeignKeyTargetSerializer(data=data)
|
self.assertTrue(serializer.is_valid())
|
||||||
# self.assertTrue(serializer.is_valid())
|
obj = serializer.save()
|
||||||
# obj = serializer.save()
|
self.assertEquals(serializer.data, data)
|
||||||
# self.assertEquals(serializer.data, data)
|
self.assertEqual(obj.name, u'target-3')
|
||||||
# self.assertEqual(obj.name, u'target-3')
|
|
||||||
|
|
||||||
# # Ensure target 4 is added, and everything else is as expected
|
# Ensure target 4 is added, and everything else is as expected
|
||||||
# queryset = ForeignKeyTarget.objects.all()
|
queryset = ForeignKeyTarget.objects.all()
|
||||||
# serializer = ForeignKeyTargetSerializer(queryset)
|
serializer = ForeignKeyTargetSerializer(queryset)
|
||||||
# expected = [
|
expected = [
|
||||||
# {'id': 1, 'name': u'target-1', 'sources': [1, 2, 3]},
|
{'id': 1, 'name': u'target-1', 'sources': [2]},
|
||||||
# {'id': 2, 'name': u'target-2', 'sources': []},
|
{'id': 2, 'name': u'target-2', 'sources': []},
|
||||||
# {'id': 3, 'name': u'target-3', 'sources': [1, 3]},
|
{'id': 3, 'name': u'target-3', 'sources': [1, 3]},
|
||||||
# ]
|
]
|
||||||
# self.assertEquals(serializer.data, expected)
|
self.assertEquals(serializer.data, expected)
|
||||||
|
|
||||||
def test_foreign_key_update_with_invalid_null(self):
|
def test_foreign_key_update_with_invalid_null(self):
|
||||||
data = {'id': 1, 'name': u'source-1', 'target': None}
|
data = {'id': 1, 'name': u'source-1', 'target': None}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user