mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-06 21:40:13 +03:00
Merge 5a899aea1a
into fc70c0862f
This commit is contained in:
commit
ba5da9ab61
|
@ -155,15 +155,41 @@ class Field(object):
|
||||||
}
|
}
|
||||||
default_validators = []
|
default_validators = []
|
||||||
default_empty_html = empty
|
default_empty_html = empty
|
||||||
initial = None
|
|
||||||
|
|
||||||
def __init__(self, read_only=False, write_only=False,
|
# allows subclasses to change defaults
|
||||||
required=None, default=empty, initial=empty, source=None,
|
read_only = False
|
||||||
label=None, help_text=None, style=None,
|
write_only = False
|
||||||
error_messages=None, validators=None, allow_null=False):
|
required = None
|
||||||
|
default = empty
|
||||||
|
initial = None
|
||||||
|
source = None
|
||||||
|
label = None
|
||||||
|
help_text = None
|
||||||
|
style = None
|
||||||
|
error_messages = None
|
||||||
|
validators = None
|
||||||
|
allow_null = False
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
self._creation_counter = Field._creation_counter
|
self._creation_counter = Field._creation_counter
|
||||||
Field._creation_counter += 1
|
Field._creation_counter += 1
|
||||||
|
|
||||||
|
# precedence is given to kwargs over class attributes.
|
||||||
|
# you can create a subclass of a Field for maximum reuse while still
|
||||||
|
# needing a one-off instance where you need to change an attribute.
|
||||||
|
read_only = kwargs.pop('read_only', self.read_only)
|
||||||
|
write_only = kwargs.pop('write_only', self.write_only)
|
||||||
|
required = kwargs.pop('required', self.required)
|
||||||
|
default = kwargs.pop('default', self.default)
|
||||||
|
initial = kwargs.pop('initial', self.initial)
|
||||||
|
source = kwargs.pop('source', self.source)
|
||||||
|
label = kwargs.pop('label', self.label)
|
||||||
|
help_text = kwargs.pop('help_text', self.help_text)
|
||||||
|
style = kwargs.pop('style', self.style)
|
||||||
|
error_messages = kwargs.pop('error_messages', self.error_messages)
|
||||||
|
validators = kwargs.pop('validators', self.validators)
|
||||||
|
allow_null = kwargs.pop('allow_null', self.allow_null)
|
||||||
|
|
||||||
# If `required` is unset, then use `True` unless a default is provided.
|
# If `required` is unset, then use `True` unless a default is provided.
|
||||||
if required is None:
|
if required is None:
|
||||||
required = default is empty and not read_only
|
required = default is empty and not read_only
|
||||||
|
@ -179,7 +205,7 @@ class Field(object):
|
||||||
self.required = required
|
self.required = required
|
||||||
self.default = default
|
self.default = default
|
||||||
self.source = source
|
self.source = source
|
||||||
self.initial = self.initial if (initial is empty) else initial
|
self.initial = initial
|
||||||
self.label = label
|
self.label = label
|
||||||
self.help_text = help_text
|
self.help_text = help_text
|
||||||
self.style = {} if style is None else style
|
self.style = {} if style is None else style
|
||||||
|
@ -552,18 +578,21 @@ class CharField(Field):
|
||||||
'min_length': _('Ensure this field has at least {min_length} characters.')
|
'min_length': _('Ensure this field has at least {min_length} characters.')
|
||||||
}
|
}
|
||||||
initial = ''
|
initial = ''
|
||||||
|
allow_blank = False
|
||||||
|
max_length = None
|
||||||
|
min_length = None
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
self.allow_blank = kwargs.pop('allow_blank', self.allow_blank)
|
||||||
max_length = kwargs.pop('max_length', None)
|
self.max_length = kwargs.pop('max_length', self.max_length)
|
||||||
min_length = kwargs.pop('min_length', None)
|
self.min_length = kwargs.pop('min_length', self.min_length)
|
||||||
super(CharField, self).__init__(**kwargs)
|
super(CharField, self).__init__(**kwargs)
|
||||||
if max_length is not None:
|
if self.max_length is not None:
|
||||||
message = self.error_messages['max_length'].format(max_length=max_length)
|
message = self.error_messages['max_length'].format(max_length=self.max_length)
|
||||||
self.validators.append(MaxLengthValidator(max_length, message=message))
|
self.validators.append(MaxLengthValidator(self.max_length, message=message))
|
||||||
if min_length is not None:
|
if self.min_length is not None:
|
||||||
message = self.error_messages['min_length'].format(min_length=min_length)
|
message = self.error_messages['min_length'].format(min_length=self.min_length)
|
||||||
self.validators.append(MinLengthValidator(min_length, message=message))
|
self.validators.append(MinLengthValidator(self.min_length, message=message))
|
||||||
|
|
||||||
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,
|
||||||
|
@ -660,17 +689,19 @@ class IntegerField(Field):
|
||||||
'max_string_length': _('String value too large')
|
'max_string_length': _('String value too large')
|
||||||
}
|
}
|
||||||
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
|
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
|
||||||
|
max_value = None
|
||||||
|
min_value = None
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
max_value = kwargs.pop('max_value', None)
|
self.max_value = kwargs.pop('max_value', self.max_value)
|
||||||
min_value = kwargs.pop('min_value', None)
|
self.min_value = kwargs.pop('min_value', self.min_value)
|
||||||
super(IntegerField, self).__init__(**kwargs)
|
super(IntegerField, self).__init__(**kwargs)
|
||||||
if max_value is not None:
|
if self.max_value is not None:
|
||||||
message = self.error_messages['max_value'].format(max_value=max_value)
|
message = self.error_messages['max_value'].format(max_value=self.max_value)
|
||||||
self.validators.append(MaxValueValidator(max_value, message=message))
|
self.validators.append(MaxValueValidator(self.max_value, message=message))
|
||||||
if min_value is not None:
|
if self.min_value is not None:
|
||||||
message = self.error_messages['min_value'].format(min_value=min_value)
|
message = self.error_messages['min_value'].format(min_value=self.min_value)
|
||||||
self.validators.append(MinValueValidator(min_value, message=message))
|
self.validators.append(MinValueValidator(self.min_value, message=message))
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
|
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
|
||||||
|
@ -694,17 +725,19 @@ class FloatField(Field):
|
||||||
'max_string_length': _('String value too large')
|
'max_string_length': _('String value too large')
|
||||||
}
|
}
|
||||||
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
|
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
|
||||||
|
max_value = None
|
||||||
|
min_value = None
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
max_value = kwargs.pop('max_value', None)
|
self.max_value = kwargs.pop('max_value', self.max_value)
|
||||||
min_value = kwargs.pop('min_value', None)
|
self.min_value = kwargs.pop('min_value', self.min_value)
|
||||||
super(FloatField, self).__init__(**kwargs)
|
super(FloatField, self).__init__(**kwargs)
|
||||||
if max_value is not None:
|
if self.max_value is not None:
|
||||||
message = self.error_messages['max_value'].format(max_value=max_value)
|
message = self.error_messages['max_value'].format(max_value=self.max_value)
|
||||||
self.validators.append(MaxValueValidator(max_value, message=message))
|
self.validators.append(MaxValueValidator(self.max_value, message=message))
|
||||||
if min_value is not None:
|
if self.min_value is not None:
|
||||||
message = self.error_messages['min_value'].format(min_value=min_value)
|
message = self.error_messages['min_value'].format(min_value=self.min_value)
|
||||||
self.validators.append(MinValueValidator(min_value, message=message))
|
self.validators.append(MinValueValidator(self.min_value, message=message))
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
|
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
|
||||||
|
@ -730,20 +763,26 @@ class DecimalField(Field):
|
||||||
'max_string_length': _('String value too large')
|
'max_string_length': _('String value too large')
|
||||||
}
|
}
|
||||||
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
|
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
|
||||||
|
max_value = None
|
||||||
|
min_value = None
|
||||||
|
# todo: max_digits = None
|
||||||
|
# todo: decimal_places = None
|
||||||
|
|
||||||
coerce_to_string = api_settings.COERCE_DECIMAL_TO_STRING
|
coerce_to_string = api_settings.COERCE_DECIMAL_TO_STRING
|
||||||
|
|
||||||
def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None, **kwargs):
|
def __init__(self, max_digits, decimal_places, coerce_to_string=None, **kwargs):
|
||||||
self.max_digits = max_digits
|
self.max_digits = max_digits
|
||||||
self.decimal_places = decimal_places
|
self.decimal_places = decimal_places
|
||||||
self.coerce_to_string = coerce_to_string if (coerce_to_string is not None) else self.coerce_to_string
|
self.coerce_to_string = coerce_to_string if (coerce_to_string is not None) else self.coerce_to_string
|
||||||
|
self.max_value = kwargs.pop('max_value', self.max_value)
|
||||||
|
self.min_value = kwargs.pop('min_value', self.min_value)
|
||||||
super(DecimalField, self).__init__(**kwargs)
|
super(DecimalField, self).__init__(**kwargs)
|
||||||
if max_value is not None:
|
if self.max_value is not None:
|
||||||
message = self.error_messages['max_value'].format(max_value=max_value)
|
message = self.error_messages['max_value'].format(max_value=self.max_value)
|
||||||
self.validators.append(MaxValueValidator(max_value, message=message))
|
self.validators.append(MaxValueValidator(self.max_value, message=message))
|
||||||
if min_value is not None:
|
if self.min_value is not None:
|
||||||
message = self.error_messages['min_value'].format(min_value=min_value)
|
message = self.error_messages['min_value'].format(min_value=self.min_value)
|
||||||
self.validators.append(MinValueValidator(min_value, message=message))
|
self.validators.append(MinValueValidator(self.min_value, message=message))
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
"""
|
"""
|
||||||
|
@ -817,10 +856,10 @@ class DateTimeField(Field):
|
||||||
input_formats = api_settings.DATETIME_INPUT_FORMATS
|
input_formats = api_settings.DATETIME_INPUT_FORMATS
|
||||||
default_timezone = timezone.get_default_timezone() if settings.USE_TZ else None
|
default_timezone = timezone.get_default_timezone() if settings.USE_TZ else None
|
||||||
|
|
||||||
def __init__(self, format=empty, input_formats=None, default_timezone=None, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.format = format if format is not empty else self.format
|
self.format = kwargs.pop('format', self.format)
|
||||||
self.input_formats = input_formats if input_formats is not None else self.input_formats
|
self.default_timezone = kwargs.pop('default_timezone', self.default_timezone)
|
||||||
self.default_timezone = default_timezone if default_timezone is not None else self.default_timezone
|
self.input_formats = kwargs.pop('input_formats', self.input_formats)
|
||||||
super(DateTimeField, self).__init__(*args, **kwargs)
|
super(DateTimeField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def enforce_timezone(self, value):
|
def enforce_timezone(self, value):
|
||||||
|
@ -881,9 +920,9 @@ class DateField(Field):
|
||||||
format = api_settings.DATE_FORMAT
|
format = api_settings.DATE_FORMAT
|
||||||
input_formats = api_settings.DATE_INPUT_FORMATS
|
input_formats = api_settings.DATE_INPUT_FORMATS
|
||||||
|
|
||||||
def __init__(self, format=empty, input_formats=None, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.format = format if format is not empty else self.format
|
self.format = kwargs.pop('format', self.format)
|
||||||
self.input_formats = input_formats if input_formats is not None else self.input_formats
|
self.input_formats = kwargs.pop('input_formats', self.input_formats)
|
||||||
super(DateField, self).__init__(*args, **kwargs)
|
super(DateField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_internal_value(self, value):
|
def to_internal_value(self, value):
|
||||||
|
@ -938,9 +977,9 @@ class TimeField(Field):
|
||||||
format = api_settings.TIME_FORMAT
|
format = api_settings.TIME_FORMAT
|
||||||
input_formats = api_settings.TIME_INPUT_FORMATS
|
input_formats = api_settings.TIME_INPUT_FORMATS
|
||||||
|
|
||||||
def __init__(self, format=empty, input_formats=None, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.format = format if format is not empty else self.format
|
self.format = kwargs.pop('format', self.format)
|
||||||
self.input_formats = input_formats if input_formats is not None else self.input_formats
|
self.input_formats = kwargs.pop('input_formats', self.input_formats)
|
||||||
super(TimeField, self).__init__(*args, **kwargs)
|
super(TimeField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_internal_value(self, value):
|
def to_internal_value(self, value):
|
||||||
|
@ -991,8 +1030,17 @@ class ChoiceField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid_choice': _('`{input}` is not a valid choice.')
|
'invalid_choice': _('`{input}` is not a valid choice.')
|
||||||
}
|
}
|
||||||
|
allow_blank = False
|
||||||
|
choices = None
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if args:
|
||||||
|
choices = args[0]
|
||||||
|
else:
|
||||||
|
choices = kwargs.pop('choices', self.choices)
|
||||||
|
# not available on class or as kwarg
|
||||||
|
assert choices is not None, 'need to specify `choices`.'
|
||||||
|
|
||||||
def __init__(self, choices, **kwargs):
|
|
||||||
# Allow either single or paired choices style:
|
# Allow either single or paired choices style:
|
||||||
# choices = [1, 2, 3]
|
# choices = [1, 2, 3]
|
||||||
# choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
|
# choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
|
||||||
|
@ -1012,7 +1060,7 @@ class ChoiceField(Field):
|
||||||
(six.text_type(key), key) for key in self.choices.keys()
|
(six.text_type(key), key) for key in self.choices.keys()
|
||||||
])
|
])
|
||||||
|
|
||||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
self.allow_blank = kwargs.pop('allow_blank', self.allow_blank)
|
||||||
|
|
||||||
super(ChoiceField, self).__init__(**kwargs)
|
super(ChoiceField, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
@ -1071,10 +1119,12 @@ class FileField(Field):
|
||||||
'max_length': _('Ensure this filename has at most {max_length} characters (it has {length}).'),
|
'max_length': _('Ensure this filename has at most {max_length} characters (it has {length}).'),
|
||||||
}
|
}
|
||||||
use_url = api_settings.UPLOADED_FILES_USE_URL
|
use_url = api_settings.UPLOADED_FILES_USE_URL
|
||||||
|
max_length = None
|
||||||
|
allow_empty_file = False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.max_length = kwargs.pop('max_length', None)
|
self.max_length = kwargs.pop('max_length', self.max_length)
|
||||||
self.allow_empty_file = kwargs.pop('allow_empty_file', False)
|
self.allow_empty_file = kwargs.pop('allow_empty_file', self.allow_empty_file)
|
||||||
self.use_url = kwargs.pop('use_url', self.use_url)
|
self.use_url = kwargs.pop('use_url', self.use_url)
|
||||||
super(FileField, self).__init__(*args, **kwargs)
|
super(FileField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -1324,16 +1374,17 @@ class ModelField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'max_length': _('Ensure this field has no more than {max_length} characters.'),
|
'max_length': _('Ensure this field has no more than {max_length} characters.'),
|
||||||
}
|
}
|
||||||
|
max_length = None
|
||||||
|
|
||||||
def __init__(self, model_field, **kwargs):
|
def __init__(self, model_field, **kwargs):
|
||||||
self.model_field = model_field
|
self.model_field = model_field
|
||||||
# The `max_length` option is supported by Django's base `Field` class,
|
# The `max_length` option is supported by Django's base `Field` class,
|
||||||
# so we'd better support it here.
|
# so we'd better support it here.
|
||||||
max_length = kwargs.pop('max_length', None)
|
self.max_length = kwargs.pop('max_length', self.max_length)
|
||||||
super(ModelField, self).__init__(**kwargs)
|
super(ModelField, self).__init__(**kwargs)
|
||||||
if max_length is not None:
|
if self.max_length is not None:
|
||||||
message = self.error_messages['max_length'].format(max_length=max_length)
|
message = self.error_messages['max_length'].format(max_length=self.max_length)
|
||||||
self.validators.append(MaxLengthValidator(max_length, message=message))
|
self.validators.append(MaxLengthValidator(self.max_length, message=message))
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
rel = getattr(self.model_field, 'rel', None)
|
rel = getattr(self.model_field, 'rel', None)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user