diff options
| -rw-r--r-- | rest_framework/serializers.py | 19 | ||||
| -rw-r--r-- | tests/test_model_serializer.py | 24 |
2 files changed, 42 insertions, 1 deletions
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index a4140c0f..d417ca80 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -653,7 +653,24 @@ class ModelSerializer(Serializer): if relation_info.to_many and (field_name in validated_attrs): many_to_many[field_name] = validated_attrs.pop(field_name) - instance = ModelClass.objects.create(**validated_attrs) + try: + instance = ModelClass.objects.create(**validated_attrs) + except TypeError as exc: + msg = ( + 'Got a `TypeError` when calling `%s.objects.create()`. ' + 'This may be because you have a writable field on the ' + 'serializer class that is not a valid argument to ' + '`%s.objects.create()`. You may need to make the field ' + 'read-only, or override the %s.create() method to handle ' + 'this correctly.\nOriginal exception text was: %s.' % + ( + ModelClass.__name__, + ModelClass.__name__, + self.__class__.__name__, + exc + ) + ) + raise TypeError(msg) # Save many-to-many relationships after the instance is created. if many_to_many: diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index 3aec0da0..1bcd58e0 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -26,6 +26,10 @@ class CustomField(models.Field): pass +class OneFieldModel(models.Model): + char_field = models.CharField(max_length=100) + + class RegularFieldsModel(models.Model): """ A model class for testing regular flat fields. @@ -68,6 +72,26 @@ class FieldOptionsModel(models.Model): choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES) +class TestModelSerializer(TestCase): + def test_create_method(self): + class TestSerializer(serializers.ModelSerializer): + non_model_field = serializers.CharField() + + class Meta: + model = OneFieldModel + fields = ('char_field', 'non_model_field') + + serializer = TestSerializer(data={ + 'char_field': 'foo', + 'non_model_field': 'bar', + }) + serializer.is_valid() + with self.assertRaises(TypeError) as excinfo: + serializer.save() + msginitial = 'Got a `TypeError` when calling `OneFieldModel.objects.create()`.' + assert str(excinfo.exception).startswith(msginitial) + + class TestRegularFieldMappings(TestCase): def test_regular_fields(self): """ |
