Skip to content

Commit e9ae9eb

Browse files
authored
Added ChoiceValidator (#5)
1 parent 1aac5a1 commit e9ae9eb

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed

docs/api-guid/validators.md

+19
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ This validator checks the string against a regular expression.
138138
validator = RegexValidator(r'\d+', True)
139139
validator('test')
140140

141+
## ChoiceValidator
142+
143+
This validator checks a value for an entry in a predefined list of values.
144+
145+
**Signature**: `ChoiceValidator(choices, message=None)`
146+
147+
- `choices` Valid values. Iter object. If `list`, `tuple`, `set` check into iter object. If `dict`, check key.
148+
- `message` The short message should fall out on validation error.
149+
150+
**Example**:
151+
152+
validator = ChoiceValidator([1, 2, 3])
153+
validator(2)
154+
155+
try:
156+
validator(15)
157+
except ValidationError:
158+
pass
159+
141160
---
142161

143162
# Writing custom validators

docs/release-notes.md

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ Medium version numbers (0.x.0) may include API changes, in line with the [deprec
88

99
Major version numbers (x.0.0) are reserved for substantial project milestones.
1010

11+
### 0.2.2
12+
13+
**Date:** [15th Jule 2019]
14+
15+
* Added [`ChoiceValidator`][ChoiceValidator] in [`serializers.validators`][Validators].
16+
1117
### 0.2.1
1218

1319
**Date:** [22th May 2019]
@@ -90,4 +96,6 @@ Major version numbers (x.0.0) are reserved for substantial project milestones.
9096
[SerializerMethodField]: api-guid/fields.md#-serializermethodfield
9197
[InheritSerializers]: api-guid/serializers.md#serializer-inheritance
9298
[RegexValidator]: api-guid/validators.md#regexvalidator
99+
[ChoiceValidator]: api-guid/validators.md#choicevalidator
93100
[Serializers]: api-guid/serializers.md
101+
[Validators]: api-guid/validators.md

rest_framework/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
__/ |
99
|___/
1010
"""
11-
VERSION = (0, 2, 1)
11+
VERSION = (0, 2, 2)
1212

1313
__title__ = 'Python-Rest-Framework'
1414
__author__ = 'Deys Timofey'

rest_framework/serializers/validators.py

+32
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,35 @@ def __call__(self, value):
219219
"""
220220
if not (self.inverse_match is not bool(self.regex.search(value))):
221221
raise ValidationError(self.message)
222+
223+
224+
class ChoiceValidator(BaseValidator):
225+
"""
226+
Validator for validation choice field.
227+
228+
"""
229+
message = 'Value must be one of `{allowed_values}`.'
230+
231+
def __init__(self, choices, *args, **kwargs):
232+
"""
233+
Validator for validation choice field.
234+
235+
:param Union[iter, dict] choices: Valid choices values.
236+
237+
"""
238+
try:
239+
iter(choices)
240+
except TypeError:
241+
raise ValueError('`choices=` must be iter or dict. Reality: `{}`.'.format(type(choices)))
242+
super().__init__(*args, **kwargs)
243+
self.choices = choices
244+
245+
def __call__(self, value: object):
246+
"""
247+
Validation.
248+
249+
:param object value: Object for validation.
250+
251+
"""
252+
if value not in self.choices:
253+
raise ValidationError(self.message.format(**dict(allowed_values=self.choices)))

rest_framework/tests/test_validators.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from rest_framework.serializers.validators import (
1010
RegexValidator, BaseValidator, RequiredValidator, MinLengthValidator, MaxLengthValidator,
11-
MinValueValidator, MaxValueValidator
11+
MinValueValidator, MaxValueValidator, ChoiceValidator
1212
)
1313
from rest_framework.serializers.exceptions import ValidationError
1414

@@ -172,3 +172,17 @@ class RegexValidatorTestCase(ValidatorTestCases):
172172
{'init': {'regex': r'\d+', 'message': 'test'}, 'data': 'test', 'message': 'test'},
173173
{'init': {'regex': r'\d+', 'inverse_match': True}, 'data': 'test'}
174174
)
175+
176+
177+
class ChoiceValidatorTestCase(ValidatorTestCases):
178+
"""
179+
Testing ChoiceValidator.
180+
181+
"""
182+
validator_class = ChoiceValidator
183+
cases = (
184+
{'init': {'choices': [1, 2, 3]}, 'data': 3},
185+
{'init': {'choices': {1: 1, 2: 2, 3: 3}}, 'data': 2},
186+
{'init': {'choices': [1, 2, 3]}, 'data': 'asdasd', 'message': 'Value must be one of `[1, 2, 3]`.'},
187+
{'init': {'choices': [1, 2, 3], 'message': 'test'}, 'data': 'test', 'message': 'test'},
188+
)

0 commit comments

Comments
 (0)