This commit is contained in:
Charlie Denton 2014-08-18 14:56:17 +00:00
commit db329a8068
3 changed files with 60 additions and 1 deletions

View File

@ -966,7 +966,7 @@ class ModelSerializer(Serializer):
# Nested forward relations - These need to be marked so we can save
# them before saving the parent model instance.
for field_name in attrs.keys():
if isinstance(self.fields.get(field_name, None), Serializer):
if isinstance(self.fields.get(field_name, None), ModelSerializer):
nested_forward_relations[field_name] = attrs[field_name]
# Create an empty instance of the model

View File

@ -1,4 +1,7 @@
from __future__ import unicode_literals
import json
from django.db import models
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
@ -15,6 +18,20 @@ class CustomField(models.CharField):
super(CustomField, self).__init__(*args, **kwargs)
class BasicJSONField(models.Field):
def to_python(self, value):
try:
return json.loads(value)
except:
return value
def get_db_prep_value(self, value, *args, **kwargs):
return json.dumps(value)
def get_internal_type(self):
return 'TextField'
class RESTFrameworkModel(models.Model):
"""
Base for test models that sets app_label, so they play nicely.
@ -168,6 +185,12 @@ class NullableOneToOneSource(RESTFrameworkModel):
related_name='nullable_source')
class Project(RESTFrameworkModel):
"""A model with a JSON field to test nested serializers."""
name = models.CharField(max_length=100)
milestones = BasicJSONField()
# Serializer used to test BasicModel
class BasicModelSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -247,6 +247,42 @@ class WritableNestedSerializerObjectTests(TestCase):
self.assertEqual(serializer.object, expected_object)
class WritableNestedSerializerFieldTests(TestCase):
"""
Nested serializers should not be assumed to reference nested models.
In this case, MilestoneSerializer is used to control the data going into
a JSON field, "milestones".
"""
def setUp(self):
class MilestoneSerializer(serializers.Serializer):
name = serializers.CharField()
class ProjectSerializer(serializers.ModelSerializer):
name = serializers.CharField()
milestones = MilestoneSerializer(many=True)
class Meta:
model = models.Project
self.ProjectSerializer = ProjectSerializer
def test_deserialize(self):
data = {
'name': 'The Awesome API Project',
'milestones': [
{'name': 'Prototype'},
{'name': 'Minumum viable product'},
{'name': 'World domination'},
],
}
expected_object = models.Project(**data)
serializer = self.ProjectSerializer(data=data)
self.assertTrue(serializer.is_valid())
obj = serializer.save()
self.assertEqual(obj.milestones, expected_object.milestones)
class ForeignKeyNestedSerializerUpdateTests(TestCase):
def setUp(self):
class Artist(object):