Skip to content

Commit ad060aa

Browse files
More helpful error message when default .create fails. Closes #2013.
1 parent 4e03518 commit ad060aa

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

rest_framework/serializers.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
)
3535
import copy
3636
import inspect
37+
import sys
3738
import warnings
3839

3940
# Note: We do the following so that users of the framework can use this style:
@@ -593,7 +594,18 @@ def create(self, validated_attrs):
593594
if relation_info.to_many and (field_name in validated_attrs):
594595
many_to_many[field_name] = validated_attrs.pop(field_name)
595596

596-
instance = ModelClass.objects.create(**validated_attrs)
597+
try:
598+
instance = ModelClass.objects.create(**validated_attrs)
599+
except TypeError as exc:
600+
msg = (
601+
'The mentioned argument might be a field on the serializer '
602+
'that is not part of the model. You need to override the '
603+
'create() method in your ModelSerializer subclass to support '
604+
'this.')
605+
six.reraise(
606+
type(exc),
607+
type(exc)(str(exc) + '. ' + msg),
608+
sys.exc_info()[2])
597609

598610
# Save many-to-many relationships after the instance is created.
599611
if many_to_many:

tests/test_model_serializer.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from django.db import models
1111
from django.test import TestCase
1212
from rest_framework import serializers
13+
import pytest
1314

1415

1516
def dedent(blocktext):
@@ -26,6 +27,10 @@ class CustomField(models.Field):
2627
pass
2728

2829

30+
class OneFieldModel(models.Model):
31+
char_field = models.CharField(max_length=100)
32+
33+
2934
class RegularFieldsModel(models.Model):
3035
"""
3136
A model class for testing regular flat fields.
@@ -68,6 +73,29 @@ class FieldOptionsModel(models.Model):
6873
choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES)
6974

7075

76+
class TestModelSerializer(TestCase):
77+
def test_create_method(self):
78+
class TestSerializer(serializers.ModelSerializer):
79+
non_model_field = serializers.CharField()
80+
81+
class Meta:
82+
model = OneFieldModel
83+
fields = ('char_field', 'non_model_field')
84+
85+
serializer = TestSerializer(data={
86+
'char_field': 'foo',
87+
'non_model_field': 'bar',
88+
})
89+
serializer.is_valid()
90+
with pytest.raises(TypeError):
91+
serializer.save()
92+
93+
try:
94+
serializer.save()
95+
except TypeError as exc:
96+
assert 'ModelSerializer' in str(exc)
97+
98+
7199
class TestRegularFieldMappings(TestCase):
72100
def test_regular_fields(self):
73101
"""

0 commit comments

Comments
 (0)