Skip to content
Prev Previous commit
Next Next commit
Refactor the message generation to delay the formatting.
  • Loading branch information
xordoquy committed Oct 19, 2015
commit 3a4be046bd85d96f8525d1de5551595a55a939cd
13 changes: 0 additions & 13 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,24 +114,11 @@ def get_model_name(model_cls):
return model_cls._meta.module_name




class CustomValidatorMessage(object):
def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message)
self.format = kwargs.pop('string_format', '%')
super(CustomValidatorMessage, self).__init__(*args, **kwargs)

def __call__(self, value):
cleaned = self.clean(value)
params = {'limit_value': self.limit_value, 'show_value': cleaned, 'value': value}
if self.compare(cleaned, self.limit_value):
message = self.message
if self.format == '{':
args = {self.code: self.limit_value}
message = message.format(**args)
raise ValidationError(message, code=self.code, params=params)


class MinValueValidator(CustomValidatorMessage, MinValueValidator):
pass
Expand Down
38 changes: 19 additions & 19 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from django.utils import six, timezone
from django.utils.dateparse import parse_date, parse_datetime, parse_time
from django.utils.encoding import is_protected_type, smart_text
from django.utils.functional import cached_property
from django.utils.functional import cached_property, lazy
from django.utils.ipv6 import clean_ipv6_address
from django.utils.translation import ugettext_lazy as _

Expand Down Expand Up @@ -675,11 +675,11 @@ def __init__(self, **kwargs):
self.min_length = kwargs.pop('min_length', None)
super(CharField, self).__init__(**kwargs)
if self.max_length is not None:
message = self.error_messages['max_length']
self.validators.append(MaxLengthValidator(self.max_length, message=message, string_format='{'))
message = lazy(self.error_messages['max_length'].format, str)(max_length=self.max_length)
self.validators.append(MaxLengthValidator(self.max_length, message=message))
if self.min_length is not None:
message = self.error_messages['min_length']
self.validators.append(MinLengthValidator(self.min_length, message=message, string_format='{'))
message = lazy(self.error_messages['min_length'].format, str)(min_length=self.min_length)
self.validators.append(MinLengthValidator(self.min_length, message=message))

def run_validation(self, data=empty):
# Test for the empty string here so that it does not get validated,
Expand Down Expand Up @@ -820,11 +820,11 @@ def __init__(self, **kwargs):
self.min_value = kwargs.pop('min_value', None)
super(IntegerField, self).__init__(**kwargs)
if self.max_value is not None:
message = self.error_messages['max_value']
self.validators.append(MaxValueValidator(self.max_value, message=message, string_format='{'))
message = lazy(self.error_messages['max_value'].format, str)(max_value=self.max_value)
self.validators.append(MaxValueValidator(self.max_value, message=message))
if self.min_value is not None:
message = self.error_messages['min_value']
self.validators.append(MinValueValidator(self.min_value, message=message, string_format='{'))
message = lazy(self.error_messages['min_value'].format, str)(min_value=self.min_value)
self.validators.append(MinValueValidator(self.min_value, message=message))

def to_internal_value(self, data):
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
Expand Down Expand Up @@ -854,11 +854,11 @@ def __init__(self, **kwargs):
self.min_value = kwargs.pop('min_value', None)
super(FloatField, self).__init__(**kwargs)
if self.max_value is not None:
message = self.error_messages['max_value']
self.validators.append(MaxValueValidator(self.max_value, message=message, string_format='{'))
message = lazy(self.error_messages['max_value'].format, str)(max_value=self.max_value)
self.validators.append(MaxValueValidator(self.max_value, message=message))
if self.min_value is not None:
message = self.error_messages['min_value']
self.validators.append(MinValueValidator(self.min_value, message=message, string_format='{'))
message = lazy(self.error_messages['min_value'].format, str)(min_value=self.min_value)
self.validators.append(MinValueValidator(self.min_value, message=message))

def to_internal_value(self, data):
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
Expand Down Expand Up @@ -903,11 +903,11 @@ def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=
super(DecimalField, self).__init__(**kwargs)

if self.max_value is not None:
message = self.error_messages['max_value']
self.validators.append(MaxValueValidator(self.max_value, message=message, string_format='{'))
message = lazy(self.error_messages['max_value'].format, str)(max_value=self.max_value)
self.validators.append(MaxValueValidator(self.max_value, message=message))
if self.min_value is not None:
message = self.error_messages['min_value']
self.validators.append(MinValueValidator(self.min_value, message=message, string_format='{'))
message = lazy(self.error_messages['min_value'].format, str)(min_value=self.min_value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Is str really correct given either py2 or py3?
  2. Should we wrap lazy(x, str)(...) up in a shortcut lazy_format(x)(...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will double check for str but I mostly copy/pasted the way Django does with ugettext_lazy so it should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch !

self.validators.append(MinValueValidator(self.min_value, message=message))

def to_internal_value(self, data):
"""
Expand Down Expand Up @@ -1606,8 +1606,8 @@ def __init__(self, model_field, **kwargs):
max_length = kwargs.pop('max_length', None)
super(ModelField, self).__init__(**kwargs)
if max_length is not None:
message = self.error_messages['max_length']
self.validators.append(MaxLengthValidator(max_length, message=message, string_format='{'))
message = lazy(self.error_messages['max_length'].format, str)(max_length=max_length)
self.validators.append(MaxLengthValidator(max_length, message=message))

def to_internal_value(self, data):
rel = getattr(self.model_field, 'rel', None)
Expand Down