From 023405b6a22abb0ba34aa37c35557261d0872fcc Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 6 Aug 2018 07:15:57 +0800 Subject: [PATCH 1/2] add feature: extra_validators in serializer mete class --- rest_framework/serializers.py | 28 ++++++++++++++++++++++++++++ tests/test_model_serializer.py | 30 +++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 43c7972a4..979a4764f 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -1026,6 +1026,8 @@ class ModelSerializer(Serializer): field_names, declared_fields, extra_kwargs ) + extra_validators = self.get_extra_validators() + # Determine the fields that should be included on the serializer. fields = OrderedDict() @@ -1050,6 +1052,13 @@ class ModelSerializer(Serializer): field_kwargs, extra_field_kwargs ) + extra_field_validators = extra_validators.get(field_name, []) + + # Include extra validators defined in `Meta.validators` + field_kwargs = self.include_extra_validators( + field_kwargs, extra_field_validators + ) + # Create the serializer field. fields[field_name] = field_class(**field_kwargs) @@ -1431,6 +1440,25 @@ class ModelSerializer(Serializer): return extra_kwargs, hidden_fields + def include_extra_validators(self, kwargs, extra_validators): + """ + Include any 'extra_validators' that have been included for this field, + """ + print(kwargs.get('validators', [])) + print(extra_validators) + validators = kwargs.get('validators', []) + extra_validators + if validators: + kwargs['validators'] = validators + return kwargs + + def get_extra_validators(self): + """ + Return a dictionary mapping field names to a list of + additional validators. + """ + extra_validators = copy.deepcopy(getattr(self.Meta, 'extra_validators', {})) + return extra_validators + def _get_model_fields(self, field_names, declared_fields, extra_kwargs): """ Returns all the model fields that are being mapped to by fields diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index b7d31e2bd..7e786a10b 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -14,7 +14,7 @@ from collections import OrderedDict import pytest from django.core.exceptions import ImproperlyConfigured from django.core.validators import ( - MaxValueValidator, MinLengthValidator, MinValueValidator + MaxValueValidator, MinLengthValidator, MinValueValidator, EmailValidator, URLValidator ) from django.db import models from django.test import TestCase @@ -286,6 +286,34 @@ class TestRegularFieldMappings(TestCase): """) self.assertEqual(repr(TestSerializer()), expected) + def test_extra_field_validators(self): + """ + Ensure `extra_validators` are included to generated fields. + """ + class TestModel(models.Model): + int = models.IntegerField() + email = models.CharField(unique=True) + url = models.CharField(validators=[URLValidator()]) + avatar = models.CharField() + + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = TestModel + fields = ('int', 'email', 'url', 'avatar') + extra_validators = { + 'email': [EmailValidator()], + 'avatar': [URLValidator()], + } + + expected = dedent(""" + TestSerializer(): + int = IntegerField() + email = CharField(validators=[, , ]) + url = CharField(validators=[, ]) + avatar = CharField(validators=[, ]) + """) + self.assertEqual(repr(TestSerializer()), expected) + def test_invalid_field(self): """ Field names that do not map to a model field or relationship should From 33642b3be4168b369ee25a11ecb8788f0c531ef6 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 6 Aug 2018 07:25:10 +0800 Subject: [PATCH 2/2] sort imports rename class name in test --- tests/test_model_serializer.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index 7e786a10b..a3ca98e1a 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -14,7 +14,8 @@ from collections import OrderedDict import pytest from django.core.exceptions import ImproperlyConfigured from django.core.validators import ( - MaxValueValidator, MinLengthValidator, MinValueValidator, EmailValidator, URLValidator + EmailValidator, MaxValueValidator, MinLengthValidator, MinValueValidator, + URLValidator ) from django.db import models from django.test import TestCase @@ -290,7 +291,7 @@ class TestRegularFieldMappings(TestCase): """ Ensure `extra_validators` are included to generated fields. """ - class TestModel(models.Model): + class ExtraValidatorsTestModel(models.Model): int = models.IntegerField() email = models.CharField(unique=True) url = models.CharField(validators=[URLValidator()]) @@ -298,7 +299,7 @@ class TestRegularFieldMappings(TestCase): class TestSerializer(serializers.ModelSerializer): class Meta: - model = TestModel + model = ExtraValidatorsTestModel fields = ('int', 'email', 'url', 'avatar') extra_validators = { 'email': [EmailValidator()], @@ -308,7 +309,7 @@ class TestRegularFieldMappings(TestCase): expected = dedent(""" TestSerializer(): int = IntegerField() - email = CharField(validators=[, , ]) + email = CharField(validators=[, , ]) url = CharField(validators=[, ]) avatar = CharField(validators=[, ]) """)