mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-02 11:30:12 +03:00
Switch to using native ProhibitNullCharactersValidator instead
This commit is contained in:
parent
bd72f84e4a
commit
8f84c06c50
|
@ -153,7 +153,6 @@ Corresponds to `django.db.models.fields.CharField` or `django.db.models.fields.T
|
||||||
- `max_length` - Validates that the input contains no more than this number of characters.
|
- `max_length` - Validates that the input contains no more than this number of characters.
|
||||||
- `min_length` - Validates that the input contains no fewer than this number of characters.
|
- `min_length` - Validates that the input contains no fewer than this number of characters.
|
||||||
- `allow_blank` - If set to `True` then the empty string should be considered a valid value. If set to `False` then the empty string is considered invalid and will raise a validation error. Defaults to `False`.
|
- `allow_blank` - If set to `True` then the empty string should be considered a valid value. If set to `False` then the empty string is considered invalid and will raise a validation error. Defaults to `False`.
|
||||||
- `allow_null_bytes` - If set to `False`, strings containing NULL bytes will be rejected. You may want to set this to `False` if the string is saved to a database. Defaults to `True`.
|
|
||||||
- `trim_whitespace` - If set to `True` then leading and trailing whitespace is trimmed. Defaults to `True`.
|
- `trim_whitespace` - If set to `True` then leading and trailing whitespace is trimmed. Defaults to `True`.
|
||||||
|
|
||||||
The `allow_null` option is also available for string fields, although its usage is discouraged in favor of `allow_blank`. It is valid to set both `allow_blank=True` and `allow_null=True`, but doing so means that there will be two differing types of empty value permissible for string representations, which can lead to data inconsistencies and subtle application bugs.
|
The `allow_null` option is also available for string fields, although its usage is discouraged in favor of `allow_blank`. It is valid to set both `allow_blank=True` and `allow_null=True`, but doing so means that there will be two differing types of empty value permissible for string representations, which can lead to data inconsistencies and subtle application bugs.
|
||||||
|
|
|
@ -22,6 +22,11 @@ except ImportError:
|
||||||
RegexURLResolver as URLResolver,
|
RegexURLResolver as URLResolver,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from django.core.validators import ProhibitNullCharactersValidator # noqa
|
||||||
|
except ImportError:
|
||||||
|
ProhibitNullCharactersValidator = None
|
||||||
|
|
||||||
|
|
||||||
def get_original_route(urlpattern):
|
def get_original_route(urlpattern):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -34,7 +34,8 @@ from pytz.exceptions import InvalidTimeError
|
||||||
from rest_framework import ISO_8601
|
from rest_framework import ISO_8601
|
||||||
from rest_framework.compat import (
|
from rest_framework.compat import (
|
||||||
MaxLengthValidator, MaxValueValidator, MinLengthValidator,
|
MaxLengthValidator, MaxValueValidator, MinLengthValidator,
|
||||||
MinValueValidator, unicode_repr, unicode_to_repr
|
MinValueValidator, ProhibitNullCharactersValidator, unicode_repr,
|
||||||
|
unicode_to_repr
|
||||||
)
|
)
|
||||||
from rest_framework.exceptions import ErrorDetail, ValidationError
|
from rest_framework.exceptions import ErrorDetail, ValidationError
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
|
@ -755,13 +756,11 @@ class CharField(Field):
|
||||||
'blank': _('This field may not be blank.'),
|
'blank': _('This field may not be blank.'),
|
||||||
'max_length': _('Ensure this field has no more than {max_length} characters.'),
|
'max_length': _('Ensure this field has no more than {max_length} characters.'),
|
||||||
'min_length': _('Ensure this field has at least {min_length} characters.'),
|
'min_length': _('Ensure this field has at least {min_length} characters.'),
|
||||||
'nulls': _('This field may not include NULL bytes.'),
|
|
||||||
}
|
}
|
||||||
initial = ''
|
initial = ''
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
self.allow_blank = kwargs.pop('allow_blank', False)
|
||||||
self.allow_null_bytes = kwargs.pop('allow_null_bytes', True)
|
|
||||||
self.trim_whitespace = kwargs.pop('trim_whitespace', True)
|
self.trim_whitespace = kwargs.pop('trim_whitespace', True)
|
||||||
self.max_length = kwargs.pop('max_length', None)
|
self.max_length = kwargs.pop('max_length', None)
|
||||||
self.min_length = kwargs.pop('min_length', None)
|
self.min_length = kwargs.pop('min_length', None)
|
||||||
|
@ -779,6 +778,10 @@ class CharField(Field):
|
||||||
self.validators.append(
|
self.validators.append(
|
||||||
MinLengthValidator(self.min_length, message=message))
|
MinLengthValidator(self.min_length, message=message))
|
||||||
|
|
||||||
|
# ProhibitNullCharactersValidator is None on Django < 2.0
|
||||||
|
if ProhibitNullCharactersValidator is not None:
|
||||||
|
self.validators.append(ProhibitNullCharactersValidator())
|
||||||
|
|
||||||
def run_validation(self, data=empty):
|
def run_validation(self, data=empty):
|
||||||
# Test for the empty string here so that it does not get validated,
|
# Test for the empty string here so that it does not get validated,
|
||||||
# and so that subclasses do not need to handle it explicitly
|
# and so that subclasses do not need to handle it explicitly
|
||||||
|
@ -787,8 +790,6 @@ class CharField(Field):
|
||||||
if not self.allow_blank:
|
if not self.allow_blank:
|
||||||
self.fail('blank')
|
self.fail('blank')
|
||||||
return ''
|
return ''
|
||||||
if not self.allow_null_bytes and '\0' in six.text_type(data):
|
|
||||||
self.fail('nulls')
|
|
||||||
return super(CharField, self).run_validation(data)
|
return super(CharField, self).run_validation(data)
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
|
|
|
@ -15,6 +15,7 @@ from django.utils.timezone import activate, deactivate, override, utc
|
||||||
|
|
||||||
import rest_framework
|
import rest_framework
|
||||||
from rest_framework import exceptions, serializers
|
from rest_framework import exceptions, serializers
|
||||||
|
from rest_framework.compat import ProhibitNullCharactersValidator
|
||||||
from rest_framework.fields import DjangoImageField, is_simple_callable
|
from rest_framework.fields import DjangoImageField, is_simple_callable
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -718,19 +719,15 @@ class TestCharField(FieldValues):
|
||||||
field.run_validation(' ')
|
field.run_validation(' ')
|
||||||
assert exc_info.value.detail == ['This field may not be blank.']
|
assert exc_info.value.detail == ['This field may not be blank.']
|
||||||
|
|
||||||
def test_allow_null_bytes(self):
|
@pytest.mark.skipif(ProhibitNullCharactersValidator is None, reason="Skipped on Django < 2.0")
|
||||||
field = serializers.CharField(allow_null_bytes=True)
|
def test_null_bytes(self):
|
||||||
for value in ('\0', 'foo\0', '\0foo', 'foo\0foo'):
|
field = serializers.CharField()
|
||||||
field.run_validation(value)
|
|
||||||
|
|
||||||
def test_disallow_null_bytes(self):
|
|
||||||
field = serializers.CharField(allow_null_bytes=False)
|
|
||||||
|
|
||||||
for value in ('\0', 'foo\0', '\0foo', 'foo\0foo'):
|
for value in ('\0', 'foo\0', '\0foo', 'foo\0foo'):
|
||||||
with pytest.raises(serializers.ValidationError) as exc_info:
|
with pytest.raises(serializers.ValidationError) as exc_info:
|
||||||
field.run_validation(value)
|
field.run_validation(value)
|
||||||
assert exc_info.value.detail == [
|
assert exc_info.value.detail == [
|
||||||
serializers.CharField.default_error_messages['nulls']
|
'Null characters are not allowed.'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user