More helpful error message when default .create fails. Closes #2013.

This commit is contained in:
Gregor Müllegger 2014-11-15 15:23:58 +01:00
parent 4e03518438
commit ad060aa360
2 changed files with 41 additions and 1 deletions

View File

@ -34,6 +34,7 @@ from rest_framework.validators import (
) )
import copy import copy
import inspect import inspect
import sys
import warnings import warnings
# Note: We do the following so that users of the framework can use this style: # Note: We do the following so that users of the framework can use this style:
@ -593,7 +594,18 @@ class ModelSerializer(Serializer):
if relation_info.to_many and (field_name in validated_attrs): if relation_info.to_many and (field_name in validated_attrs):
many_to_many[field_name] = validated_attrs.pop(field_name) 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 = (
'The mentioned argument might be a field on the serializer '
'that is not part of the model. You need to override the '
'create() method in your ModelSerializer subclass to support '
'this.')
six.reraise(
type(exc),
type(exc)(str(exc) + '. ' + msg),
sys.exc_info()[2])
# Save many-to-many relationships after the instance is created. # Save many-to-many relationships after the instance is created.
if many_to_many: if many_to_many:

View File

@ -10,6 +10,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator, MinLeng
from django.db import models from django.db import models
from django.test import TestCase from django.test import TestCase
from rest_framework import serializers from rest_framework import serializers
import pytest
def dedent(blocktext): def dedent(blocktext):
@ -26,6 +27,10 @@ class CustomField(models.Field):
pass pass
class OneFieldModel(models.Model):
char_field = models.CharField(max_length=100)
class RegularFieldsModel(models.Model): class RegularFieldsModel(models.Model):
""" """
A model class for testing regular flat fields. A model class for testing regular flat fields.
@ -68,6 +73,29 @@ class FieldOptionsModel(models.Model):
choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES) 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 pytest.raises(TypeError):
serializer.save()
try:
serializer.save()
except TypeError as exc:
assert 'ModelSerializer' in str(exc)
class TestRegularFieldMappings(TestCase): class TestRegularFieldMappings(TestCase):
def test_regular_fields(self): def test_regular_fields(self):
""" """