Skip to content

Commit

Permalink
More helpful error message when default .create fails. Closes #2013.
Browse files Browse the repository at this point in the history
  • Loading branch information
gregmuellegger committed Nov 15, 2014
1 parent 4e03518 commit ad060aa
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
14 changes: 13 additions & 1 deletion rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
)
import copy
import inspect
import sys
import warnings

# Note: We do the following so that users of the framework can use this style:
Expand Down Expand Up @@ -593,7 +594,18 @@ def create(self, validated_attrs):
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 = (
'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.
if many_to_many:
Expand Down
28 changes: 28 additions & 0 deletions tests/test_model_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.db import models
from django.test import TestCase
from rest_framework import serializers
import pytest


def dedent(blocktext):
Expand All @@ -26,6 +27,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.
Expand Down Expand Up @@ -68,6 +73,29 @@ 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 pytest.raises(TypeError):
serializer.save()

try:
serializer.save()
except TypeError as exc:
assert 'ModelSerializer' in str(exc)


class TestRegularFieldMappings(TestCase):
def test_regular_fields(self):
"""
Expand Down

0 comments on commit ad060aa

Please sign in to comment.