From 486f0a93678cd71a3d8cc5c5a6717de4b97b7fa5 Mon Sep 17 00:00:00 2001 From: Ilias Kiourktsidis Date: Mon, 23 Mar 2015 15:01:19 +0000 Subject: [PATCH] Raise error when ModelSerializer used with abstract model --- rest_framework/serializers.py | 4 ++++ rest_framework/utils/model_meta.py | 7 +++++++ tests/test_model_serializer.py | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2eef6eeb5..1e161ec16 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -823,6 +823,10 @@ class ModelSerializer(Serializer): serializer_class=self.__class__.__name__ ) ) + if model_meta.is_abstract_model(self.Meta.model): + raise ValueError( + 'Cannot use ModelSerializer with Abstract Models.' + ) declared_fields = copy.deepcopy(self._declared_fields) model = getattr(self.Meta, 'model') diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py index d92bceb98..e885be52e 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -167,3 +167,10 @@ def _merge_relationships(forward_relations, reverse_relations): list(forward_relations.items()) + list(reverse_relations.items()) ) + + +def is_abstract_model(model): + """ + Given a model class, returns a boolean True if it is abstract and False if it is not. + """ + return hasattr(model, 'Meta') and hasattr(model._meta, 'abstract') and model._meta.abstract diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index bce2008a8..dc34649ea 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -94,6 +94,30 @@ class TestModelSerializer(TestCase): msginitial = 'Got a `TypeError` when calling `OneFieldModel.objects.create()`.' assert str(excinfo.exception).startswith(msginitial) + def test_abstract_model(self): + """ + Test that trying to use ModelSerializer with Abstract Models + throws a ValueError exception. + """ + class AbstractModel(models.Model): + afield = models.CharField(max_length=255) + + class Meta: + abstract = True + + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = AbstractModel + fields = ('afield',) + + serializer = TestSerializer(data={ + 'afield': 'foo', + }) + with self.assertRaises(ValueError) as excinfo: + serializer.is_valid() + msginitial = 'Cannot use ModelSerializer with Abstract Models.' + assert str(excinfo.exception).startswith(msginitial) + class TestRegularFieldMappings(TestCase): def test_regular_fields(self):