Skip to content

Commit 1ece516

Browse files
Si Fengcarltongibson
authored andcommitted
Adjusted field validators to accept iterables. (#6282)
Closes 6280.
1 parent 6de33ef commit 1ece516

File tree

4 files changed

+56
-5
lines changed

4 files changed

+56
-5
lines changed

rest_framework/fields.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ def __init__(self, read_only=False, write_only=False,
350350
self.default_empty_html = default
351351

352352
if validators is not None:
353-
self.validators = validators[:]
353+
self.validators = list(validators)
354354

355355
# These are set up by `.bind()` when the field is added to a serializer.
356356
self.field_name = None
@@ -410,7 +410,7 @@ def validators(self, validators):
410410
self._validators = validators
411411

412412
def get_validators(self):
413-
return self.default_validators[:]
413+
return list(self.default_validators)
414414

415415
def get_initial(self):
416416
"""

rest_framework/serializers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def get_validators(self):
393393
# Used by the lazily-evaluated `validators` property.
394394
meta = getattr(self, 'Meta', None)
395395
validators = getattr(meta, 'validators', None)
396-
return validators[:] if validators else []
396+
return list(validators) if validators else []
397397

398398
def get_initial(self):
399399
if hasattr(self, 'initial_data'):
@@ -1480,7 +1480,7 @@ def get_validators(self):
14801480
# If the validators have been declared explicitly then use that.
14811481
validators = getattr(getattr(self, 'Meta', None), 'validators', None)
14821482
if validators is not None:
1483-
return validators[:]
1483+
return list(validators)
14841484

14851485
# Otherwise use the default set of validators.
14861486
return (

tests/test_fields.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,25 @@ def test_null_bytes(self):
740740
'Null characters are not allowed.'
741741
]
742742

743+
def test_iterable_validators(self):
744+
"""
745+
Ensure `validators` parameter is compatible with reasonable iterables.
746+
"""
747+
value = 'example'
748+
749+
for validators in ([], (), set()):
750+
field = serializers.CharField(validators=validators)
751+
field.run_validation(value)
752+
753+
def raise_exception(value):
754+
raise exceptions.ValidationError('Raised error')
755+
756+
for validators in ([raise_exception], (raise_exception,), set([raise_exception])):
757+
field = serializers.CharField(validators=validators)
758+
with pytest.raises(serializers.ValidationError) as exc_info:
759+
field.run_validation(value)
760+
assert exc_info.value.detail == ['Raised error']
761+
743762

744763
class TestEmailField(FieldValues):
745764
"""

tests/test_serializer.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import pytest
1111
from django.db import models
1212

13-
from rest_framework import fields, relations, serializers
13+
from rest_framework import exceptions, fields, relations, serializers
1414
from rest_framework.compat import unicode_repr
1515
from rest_framework.fields import Field
1616

@@ -183,6 +183,38 @@ def to_internal_value(self, data):
183183
assert serializer.validated_data.coords[1] == 50.941357
184184
assert serializer.errors == {}
185185

186+
def test_iterable_validators(self):
187+
"""
188+
Ensure `validators` parameter is compatible with reasonable iterables.
189+
"""
190+
data = {'char': 'abc', 'integer': 123}
191+
192+
for validators in ([], (), set()):
193+
class ExampleSerializer(serializers.Serializer):
194+
char = serializers.CharField(validators=validators)
195+
integer = serializers.IntegerField()
196+
197+
serializer = ExampleSerializer(data=data)
198+
assert serializer.is_valid()
199+
assert serializer.validated_data == data
200+
assert serializer.errors == {}
201+
202+
def raise_exception(value):
203+
raise exceptions.ValidationError('Raised error')
204+
205+
for validators in ([raise_exception], (raise_exception,), set([raise_exception])):
206+
class ExampleSerializer(serializers.Serializer):
207+
char = serializers.CharField(validators=validators)
208+
integer = serializers.IntegerField()
209+
210+
serializer = ExampleSerializer(data=data)
211+
assert not serializer.is_valid()
212+
assert serializer.data == data
213+
assert serializer.validated_data == {}
214+
assert serializer.errors == {'char': [
215+
exceptions.ErrorDetail(string='Raised error', code='invalid')
216+
]}
217+
186218

187219
class TestValidateMethod:
188220
def test_non_field_error_validate_method(self):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy