From 7415b74980824e9032b646b89c6712c09e9d7d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gregor=20M=C3=BCllegger?= Date: Sat, 15 Nov 2014 12:39:12 +0100 Subject: [PATCH] Providing meaningful error message if you forget many=True. Closes #1914. --- rest_framework/serializers.py | 11 ++++++++++- tests/test_serializer.py | 13 +++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2d5c843e5..6c1a461ed 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -70,6 +70,7 @@ class BaseSerializer(Field): self.partial = kwargs.pop('partial', False) self._context = kwargs.pop('context', {}) kwargs.pop('many', None) + kwargs.pop('many_init', None) super(BaseSerializer, self).__init__(**kwargs) def __new__(cls, *args, **kwargs): @@ -77,6 +78,14 @@ class BaseSerializer(Field): # `ListSerializer` classes instead when `many=True` is set. if kwargs.pop('many', False): return cls.many_init(*args, **kwargs) + if not kwargs.pop('many_init', False): + if not issubclass(cls, ListSerializer): + instance = kwargs.get('instance', args[0] if args else None) + if isinstance(instance, (list, tuple, models.QuerySet)): + msg = ( + 'You have passed a %s as `instance` argument but did ' + 'not set `many=True`.' % instance.__class__.__name__) + raise AssertionError(msg) return super(BaseSerializer, cls).__new__(cls, *args, **kwargs) @classmethod @@ -87,7 +96,7 @@ class BaseSerializer(Field): control which keyword arguments are passed to the parent, and which are passed to the child. """ - child_serializer = cls(*args, **kwargs) + child_serializer = cls(many_init=True, *args, **kwargs) list_kwargs = {'child': child_serializer} list_kwargs.update(dict([ (key, value) for key, value in kwargs.items() diff --git a/tests/test_serializer.py b/tests/test_serializer.py index 77d5c3199..265369591 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -1,3 +1,4 @@ +from django.db.models.query import QuerySet from rest_framework import serializers import pytest @@ -42,6 +43,18 @@ class TestSerializer: with pytest.raises(AttributeError): serializer.data + def test_missing_many_kwarg(self): + self.Serializer([], many=True) + with pytest.raises(AssertionError): + self.Serializer([]) + with pytest.raises(AssertionError): + self.Serializer(()) + with pytest.raises(AssertionError): + self.Serializer(QuerySet()) + self.Serializer(None) + self.Serializer(object()) + self.Serializer({}) + class TestValidateMethod: def test_non_field_error_validate_method(self):