mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-03 03:50:11 +03:00
Added 'use_model_error_messages' option to ModelSerializer to pass model field error messages to autogenerated serializer fields
This commit is contained in:
parent
d80259f7ce
commit
b94aefc91f
|
@ -622,6 +622,7 @@ class ModelSerializerOptions(SerializerOptions):
|
||||||
self.model = getattr(meta, 'model', None)
|
self.model = getattr(meta, 'model', None)
|
||||||
self.read_only_fields = getattr(meta, 'read_only_fields', ())
|
self.read_only_fields = getattr(meta, 'read_only_fields', ())
|
||||||
self.write_only_fields = getattr(meta, 'write_only_fields', ())
|
self.write_only_fields = getattr(meta, 'write_only_fields', ())
|
||||||
|
self.use_model_error_messages = getattr(meta, 'use_model_error_messages', False)
|
||||||
|
|
||||||
|
|
||||||
class ModelSerializer(Serializer):
|
class ModelSerializer(Serializer):
|
||||||
|
@ -782,7 +783,7 @@ class ModelSerializer(Serializer):
|
||||||
"Non-existant field '%s' specified in `write_only_fields` "
|
"Non-existant field '%s' specified in `write_only_fields` "
|
||||||
"on serializer '%s'." %
|
"on serializer '%s'." %
|
||||||
(field_name, self.__class__.__name__))
|
(field_name, self.__class__.__name__))
|
||||||
ret[field_name].write_only = True
|
ret[field_name].write_only = True
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -848,7 +849,7 @@ class ModelSerializer(Serializer):
|
||||||
if model_field.help_text is not None:
|
if model_field.help_text is not None:
|
||||||
kwargs['help_text'] = model_field.help_text
|
kwargs['help_text'] = model_field.help_text
|
||||||
|
|
||||||
if model_field.error_messages is not None:
|
if self.opts.use_model_error_messages and model_field.error_messages is not None:
|
||||||
kwargs['error_messages'] = model_field.error_messages
|
kwargs['error_messages'] = model_field.error_messages
|
||||||
|
|
||||||
# TODO: TypedChoiceField?
|
# TODO: TypedChoiceField?
|
||||||
|
|
|
@ -1842,35 +1842,51 @@ class BoolenFieldTypeTest(TestCase):
|
||||||
self.assertEqual(type(bfield), fields.BooleanField)
|
self.assertEqual(type(bfield), fields.BooleanField)
|
||||||
|
|
||||||
|
|
||||||
class ErrorMessagesOnAutogeneratedFieldsTests(TestCase):
|
class ModelErrorMessagesFieldsTests(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
class EMOAFModel(RESTFrameworkModel):
|
class ErrorMessageModel(RESTFrameworkModel):
|
||||||
char_field = models.CharField(blank=False, max_length=5, error_messages={
|
char_field = models.CharField(blank=False, max_length=5, error_messages={
|
||||||
'required': 'required',
|
|
||||||
'max_length': 'max_length %(limit_value)d',
|
'max_length': 'max_length %(limit_value)d',
|
||||||
})
|
})
|
||||||
|
int_field = models.IntegerField({
|
||||||
|
'required': 'int required model',
|
||||||
|
'invalid': 'int invalid',
|
||||||
|
})
|
||||||
|
|
||||||
|
class ErrorMessageSerializer(serializers.ModelSerializer):
|
||||||
|
int_field = serializers.IntegerField(error_messages={
|
||||||
|
'required': 'int required',
|
||||||
|
})
|
||||||
|
|
||||||
class EMOAFSerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = EMOAFModel
|
model = ErrorMessageModel
|
||||||
|
|
||||||
self.serializer_class = EMOAFSerializer
|
self.serializer_class = ErrorMessageSerializer
|
||||||
|
|
||||||
|
def error_test(self, data, expected_error_field, expected_message, enabled=False):
|
||||||
|
self.serializer_class.Meta.use_model_error_messages = enabled
|
||||||
|
|
||||||
def error_test(self, data, expected_message):
|
|
||||||
serializer = self.serializer_class(data=data)
|
serializer = self.serializer_class(data=data)
|
||||||
self.assertEqual(serializer.is_valid(), False)
|
self.assertEqual(serializer.is_valid(), False)
|
||||||
self.assertEqual(len(serializer.errors), 1)
|
self.assertEqual(len(serializer.errors), 1)
|
||||||
|
|
||||||
for (field_name, message) in serializer.errors.items():
|
for (field_name, message) in serializer.errors.items():
|
||||||
self.assertEqual('char_field', field_name)
|
self.assertEqual(expected_error_field, field_name)
|
||||||
self.assertEqual(expected_message, message[0])
|
self.assertEqual(expected_message, message[0])
|
||||||
|
|
||||||
def test_required(self):
|
def test_model_field_required(self):
|
||||||
self.error_test({}, 'required')
|
self.error_test({'int_field': 10, 'char_field': None}, 'char_field', 'This field is required.', enabled=True)
|
||||||
|
self.error_test({'int_field': 10, 'char_field': None}, 'char_field', 'This field is required.', enabled=False)
|
||||||
|
|
||||||
def test_required(self):
|
def test_model_field_validation_failure(self):
|
||||||
self.error_test({'char_field': None}, 'required')
|
self.error_test({'int_field': 10, 'char_field': 'abcdef'}, 'char_field', 'max_length 5', enabled=True)
|
||||||
|
self.error_test({'int_field': 10, 'char_field': 'abcdef'}, 'char_field', 'Ensure this value has at most 5 characters (it has 6).', enabled=False)
|
||||||
|
|
||||||
def test_max_length(self):
|
def test_serializer_field_required(self):
|
||||||
self.error_test({'char_field': 'abcdef'}, 'max_length 5')
|
self.error_test({'char_field': 'abcde'}, 'int_field', 'int required', enabled=True)
|
||||||
|
self.error_test({'char_field': 'abcde'}, 'int_field', 'int required', enabled=False)
|
||||||
|
|
||||||
|
def test_serializer_field_validation_failure(self):
|
||||||
|
self.error_test({'int_field': 'abc', 'char_field': 'abcde'}, 'int_field', 'Enter a whole number.', enabled=True)
|
||||||
|
self.error_test({'int_field': 'abc', 'char_field': 'abcde'}, 'int_field', 'Enter a whole number.', enabled=False)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user