diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 528340d697..e0f718cedc 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -11,13 +11,18 @@ import django from django.apps import apps from django.conf import settings -from django.core.exceptions import ImproperlyConfigured +from django.core.exceptions import ImproperlyConfigured, ValidationError +from django.core.validators import \ + MaxLengthValidator as DjangoMaxLengthValidator +from django.core.validators import MaxValueValidator as DjangoMaxValueValidator +from django.core.validators import \ + MinLengthValidator as DjangoMinLengthValidator +from django.core.validators import MinValueValidator as DjangoMinValueValidator from django.db import connection, models, transaction from django.template import Context, RequestContext, Template from django.utils import six from django.views.generic import View - try: from django.urls import ( NoReverseMatch, RegexURLPattern, RegexURLResolver, ResolverMatch, Resolver404, get_script_prefix, reverse, reverse_lazy, resolve @@ -293,6 +298,28 @@ def pygments_css(style): except ImportError: DecimalValidator = None +class CustomValidatorMessage(object): + """ + We need to avoid evaluation of `lazy` translated `message` in `django.core.validators.BaseValidator.__init__`. + https://github.com/django/django/blob/75ed5900321d170debef4ac452b8b3cf8a1c2384/django/core/validators.py#L297 + + Ref: https://github.com/encode/django-rest-framework/pull/5452 + """ + def __init__(self, *args, **kwargs): + self.message = kwargs.pop('message', self.message) + super(CustomValidatorMessage, self).__init__(*args, **kwargs) + +class MinValueValidator(CustomValidatorMessage, DjangoMinValueValidator): + pass + +class MaxValueValidator(CustomValidatorMessage, DjangoMaxValueValidator): + pass + +class MinLengthValidator(CustomValidatorMessage, DjangoMinLengthValidator): + pass + +class MaxLengthValidator(CustomValidatorMessage, DjangoMaxLengthValidator): + pass def set_rollback(): if hasattr(transaction, 'set_rollback'): diff --git a/rest_framework/fields.py b/rest_framework/fields.py index e17a0bf9ae..1bcdf763dc 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -13,8 +13,7 @@ from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import ObjectDoesNotExist from django.core.validators import ( - EmailValidator, MaxLengthValidator, MaxValueValidator, MinLengthValidator, - MinValueValidator, RegexValidator, URLValidator, ip_address_validators + EmailValidator, RegexValidator, URLValidator, ip_address_validators ) from django.forms import FilePathField as DjangoFilePathField from django.forms import ImageField as DjangoImageField @@ -25,14 +24,16 @@ from django.utils.duration import duration_string from django.utils.encoding import is_protected_type, smart_text from django.utils.formats import localize_input, sanitize_separators +from django.utils.functional import lazy from django.utils.ipv6 import clean_ipv6_address from django.utils.timezone import utc from django.utils.translation import ugettext_lazy as _ from rest_framework import ISO_8601 from rest_framework.compat import ( - InvalidTimeError, get_remote_field, unicode_repr, unicode_to_repr, - value_from_object + InvalidTimeError, MaxLengthValidator, MaxValueValidator, + MinLengthValidator, MinValueValidator, get_remote_field, unicode_repr, + unicode_to_repr, value_from_object ) from rest_framework.exceptions import ErrorDetail, ValidationError from rest_framework.settings import api_settings @@ -750,11 +751,17 @@ 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'].format(max_length=self.max_length) - self.validators.append(MaxLengthValidator(self.max_length, message=message)) + message = lazy( + self.error_messages['max_length'].format, + six.text_type)(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'].format(min_length=self.min_length) - self.validators.append(MinLengthValidator(self.min_length, message=message)) + message = lazy( + self.error_messages['min_length'].format, + six.text_type)(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, @@ -909,11 +916,17 @@ 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'].format(max_value=self.max_value) - self.validators.append(MaxValueValidator(self.max_value, message=message)) + message = lazy( + self.error_messages['max_value'].format, + six.text_type)(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'].format(min_value=self.min_value) - self.validators.append(MinValueValidator(self.min_value, message=message)) + message = lazy( + self.error_messages['min_value'].format, + six.text_type)(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: @@ -943,11 +956,17 @@ 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'].format(max_value=self.max_value) - self.validators.append(MaxValueValidator(self.max_value, message=message)) + message = lazy( + self.error_messages['max_value'].format, + six.text_type)(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'].format(min_value=self.min_value) - self.validators.append(MinValueValidator(self.min_value, message=message)) + message = lazy( + self.error_messages['min_value'].format, + six.text_type)(min_value=self.min_value) + self.validators.append( + MinValueValidator(self.min_value, message=message)) def to_internal_value(self, data): @@ -996,11 +1015,17 @@ 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'].format(max_value=self.max_value) - self.validators.append(MaxValueValidator(self.max_value, message=message)) + message = lazy( + self.error_messages['max_value'].format, + six.text_type)(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'].format(min_value=self.min_value) - self.validators.append(MinValueValidator(self.min_value, message=message)) + message = lazy( + self.error_messages['min_value'].format, + six.text_type)(min_value=self.min_value) + self.validators.append( + MinValueValidator(self.min_value, message=message)) def to_internal_value(self, data): """ @@ -1797,8 +1822,11 @@ 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'].format(max_length=max_length) - self.validators.append(MaxLengthValidator(max_length, message=message)) + message = lazy( + self.error_messages['max_length'].format, + six.text_type)(max_length=self.max_length) + self.validators.append( + MaxLengthValidator(self.max_length, message=message)) def to_internal_value(self, data): rel = get_remote_field(self.model_field, default=None) 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