diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 124ef68ac..7e86a7b9f 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import base64 from django.contrib.auth import authenticate from django.middleware.csrf import CsrfViewMiddleware +from django.utils.translation import ugettext_lazy as _ from rest_framework import exceptions, HTTP_HEADER_ENCODING from rest_framework.authtoken.models import Token @@ -65,16 +66,16 @@ class BasicAuthentication(BaseAuthentication): return None if len(auth) == 1: - msg = 'Invalid basic header. No credentials provided.' + msg = _("Invalid basic header. No credentials provided.") raise exceptions.AuthenticationFailed(msg) elif len(auth) > 2: - msg = 'Invalid basic header. Credentials string should not contain spaces.' + msg = _("Invalid basic header. Credentials string should not contain spaces.") raise exceptions.AuthenticationFailed(msg) try: auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':') except (TypeError, UnicodeDecodeError): - msg = 'Invalid basic header. Credentials not correctly base64 encoded' + msg = _("Invalid basic header. Credentials not correctly base64 encoded.") raise exceptions.AuthenticationFailed(msg) userid, password = auth_parts[0], auth_parts[2] @@ -86,7 +87,7 @@ class BasicAuthentication(BaseAuthentication): """ user = authenticate(username=userid, password=password) if user is None or not user.is_active: - raise exceptions.AuthenticationFailed('Invalid username/password') + raise exceptions.AuthenticationFailed(_("Invalid username/password.")) return (user, None) def authenticate_header(self, request): @@ -152,10 +153,10 @@ class TokenAuthentication(BaseAuthentication): return None if len(auth) == 1: - msg = 'Invalid token header. No credentials provided.' + msg = _("Invalid token header. No credentials provided.") raise exceptions.AuthenticationFailed(msg) elif len(auth) > 2: - msg = 'Invalid token header. Token string should not contain spaces.' + msg = _("Invalid token header. Token string should not contain spaces.") raise exceptions.AuthenticationFailed(msg) return self.authenticate_credentials(auth[1]) @@ -164,10 +165,10 @@ class TokenAuthentication(BaseAuthentication): try: token = self.model.objects.get(key=key) except self.model.DoesNotExist: - raise exceptions.AuthenticationFailed('Invalid token') + raise exceptions.AuthenticationFailed(_("Invalid token")) if not token.user.is_active: - raise exceptions.AuthenticationFailed('User inactive or deleted') + raise exceptions.AuthenticationFailed(_("User inactive or deleted")) return (token.user, token) diff --git a/rest_framework/authtoken/serializers.py b/rest_framework/authtoken/serializers.py index f31dded17..78fe6a117 100644 --- a/rest_framework/authtoken/serializers.py +++ b/rest_framework/authtoken/serializers.py @@ -17,13 +17,13 @@ class AuthTokenSerializer(serializers.Serializer): if user: if not user.is_active: - msg = _('User account is disabled.') + msg = _("User account is disabled.") raise exceptions.ValidationError(msg) else: - msg = _('Unable to log in with provided credentials.') + msg = _("Unable to log in with provided credentials.") raise exceptions.ValidationError(msg) else: - msg = _('Must include "username" and "password"') + msg = _("Must include \"username\" and \"password\"") raise exceptions.ValidationError(msg) attrs['user'] = user diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py index dfc57293e..3ca8e5380 100644 --- a/rest_framework/exceptions.py +++ b/rest_framework/exceptions.py @@ -35,7 +35,7 @@ class APIException(Exception): Subclasses should provide `.status_code` and `.default_detail` properties. """ status_code = status.HTTP_500_INTERNAL_SERVER_ERROR - default_detail = _('A server error occurred.') + default_detail = _("A server error occurred.") def __init__(self, detail=None): if detail is not None: @@ -52,7 +52,7 @@ class APIException(Exception): # built in `ValidationError`. For example: # # from rest_framework import serializers -# raise serializers.ValidationError('Value was invalid') +# raise serializers.ValidationError("Value was invalid") class ValidationError(APIException): status_code = status.HTTP_400_BAD_REQUEST @@ -70,32 +70,32 @@ class ValidationError(APIException): class ParseError(APIException): status_code = status.HTTP_400_BAD_REQUEST - default_detail = _('Malformed request.') + default_detail = _("Malformed request.") class AuthenticationFailed(APIException): status_code = status.HTTP_401_UNAUTHORIZED - default_detail = _('Incorrect authentication credentials.') + default_detail = _("Incorrect authentication credentials.") class NotAuthenticated(APIException): status_code = status.HTTP_401_UNAUTHORIZED - default_detail = _('Authentication credentials were not provided.') + default_detail = _("Authentication credentials were not provided.") class PermissionDenied(APIException): status_code = status.HTTP_403_FORBIDDEN - default_detail = _('You do not have permission to perform this action.') + default_detail = _("You do not have permission to perform this action.") class NotFound(APIException): status_code = status.HTTP_404_NOT_FOUND - default_detail = _('Not found.') + default_detail = _("Not found.") class MethodNotAllowed(APIException): status_code = status.HTTP_405_METHOD_NOT_ALLOWED - default_detail = _("Method {method} not allowed.") + default_detail = _("Method '{method}' not allowed.") def __init__(self, method, detail=None): if detail is not None: @@ -106,7 +106,7 @@ class MethodNotAllowed(APIException): class NotAcceptable(APIException): status_code = status.HTTP_406_NOT_ACCEPTABLE - default_detail = _('Could not satisfy the request Accept header.') + default_detail = _("Could not satisfy the request Accept header.") def __init__(self, detail=None, available_renderers=None): if detail is not None: @@ -131,9 +131,9 @@ class UnsupportedMediaType(APIException): class Throttled(APIException): status_code = status.HTTP_429_TOO_MANY_REQUESTS - default_detail = _('Request was throttled.') - extra_detail_singular = 'Expected available in {wait} second.' - extra_detail_plural = 'Expected available in {wait} seconds.' + default_detail = _("Request was throttled.") + extra_detail_singular = "Expected available in {wait} second." + extra_detail_plural = "Expected available in {wait} seconds." def __init__(self, wait=None, detail=None): if detail is not None: diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 0ff2b0733..8a781b356 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -149,8 +149,8 @@ class Field(object): _creation_counter = 0 default_error_messages = { - 'required': _('This field is required.'), - 'null': _('This field may not be null.') + 'required': _("This field is required."), + 'null': _("This field may not be null.") } default_validators = [] default_empty_html = empty @@ -477,7 +477,7 @@ class Field(object): class BooleanField(Field): default_error_messages = { - 'invalid': _('`{input}` is not a valid boolean.') + 'invalid': _("`{input}` is not a valid boolean.") } default_empty_html = False initial = False @@ -505,7 +505,7 @@ class BooleanField(Field): class NullBooleanField(Field): default_error_messages = { - 'invalid': _('`{input}` is not a valid boolean.') + 'invalid': _("`{input}` is not a valid boolean.") } initial = None TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True)) @@ -540,9 +540,9 @@ class NullBooleanField(Field): class CharField(Field): default_error_messages = { - 'blank': _('This field may not be blank.'), - 'max_length': _('Ensure this field has no more than {max_length} characters.'), - 'min_length': _('Ensure this field has at least {min_length} characters.') + 'blank': _("This field may not be blank."), + 'max_length': _("Ensure this field has no more than {max_length} characters."), + 'min_length': _("Ensure this field has at least {min_length} characters.") } initial = '' coerce_blank_to_null = False @@ -584,7 +584,7 @@ class CharField(Field): class EmailField(CharField): default_error_messages = { - 'invalid': _('Enter a valid email address.') + 'invalid': _("Enter a valid email address.") } def __init__(self, **kwargs): @@ -601,7 +601,7 @@ class EmailField(CharField): class RegexField(CharField): default_error_messages = { - 'invalid': _('This value does not match the required pattern.') + 'invalid': _("This value does not match the required pattern.") } def __init__(self, regex, **kwargs): @@ -637,10 +637,10 @@ class URLField(CharField): class IntegerField(Field): default_error_messages = { - 'invalid': _('A valid integer is required.'), - 'max_value': _('Ensure this value is less than or equal to {max_value}.'), - 'min_value': _('Ensure this value is greater than or equal to {min_value}.'), - 'max_string_length': _('String value too large.') + 'invalid': _("A valid integer is required."), + 'max_value': _("Ensure this value is less than or equal to {max_value}."), + 'min_value': _("Ensure this value is greater than or equal to {min_value}."), + 'max_string_length': _("String value too large.") } MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs. @@ -672,9 +672,9 @@ class IntegerField(Field): class FloatField(Field): default_error_messages = { 'invalid': _("A valid number is required."), - 'max_value': _('Ensure this value is less than or equal to {max_value}.'), - 'min_value': _('Ensure this value is greater than or equal to {min_value}.'), - 'max_string_length': _('String value too large.') + 'max_value': _("Ensure this value is less than or equal to {max_value}."), + 'min_value': _("Ensure this value is greater than or equal to {min_value}."), + 'max_string_length': _("String value too large.") } MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs. @@ -704,13 +704,13 @@ class FloatField(Field): class DecimalField(Field): default_error_messages = { - 'invalid': _('A valid number is required.'), - 'max_value': _('Ensure this value is less than or equal to {max_value}.'), - 'min_value': _('Ensure this value is greater than or equal to {min_value}.'), - 'max_digits': _('Ensure that there are no more than {max_digits} digits in total.'), - 'max_decimal_places': _('Ensure that there are no more than {max_decimal_places} decimal places.'), - 'max_whole_digits': _('Ensure that there are no more than {max_whole_digits} digits before the decimal point.'), - 'max_string_length': _('String value too large.') + 'invalid': _("A valid number is required."), + 'max_value': _("Ensure this value is less than or equal to {max_value}."), + 'min_value': _("Ensure this value is greater than or equal to {min_value}."), + 'max_digits': _("Ensure that there are no more than {max_digits} digits in total."), + 'max_decimal_places': _("Ensure that there are no more than {max_decimal_places} decimal places."), + 'max_whole_digits': _("Ensure that there are no more than {max_whole_digits} digits before the decimal point."), + 'max_string_length': _("String value too large.") } MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs. @@ -793,8 +793,8 @@ class DecimalField(Field): class DateTimeField(Field): default_error_messages = { - 'invalid': _('Datetime has wrong format. Use one of these formats instead: {format}.'), - 'date': _('Expected a datetime but got a date.'), + 'invalid': _("Datetime has wrong format. Use one of these formats instead: {format}."), + 'date': _("Expected a datetime but got a date."), } format = api_settings.DATETIME_FORMAT input_formats = api_settings.DATETIME_INPUT_FORMATS @@ -858,8 +858,8 @@ class DateTimeField(Field): class DateField(Field): default_error_messages = { - 'invalid': _('Date has wrong format. Use one of these formats instead: {format}.'), - 'datetime': _('Expected a date but got a datetime.'), + 'invalid': _("Date has wrong format. Use one of these formats instead: {format}."), + 'datetime': _("Expected a date but got a datetime."), } format = api_settings.DATE_FORMAT input_formats = api_settings.DATE_INPUT_FORMATS @@ -916,7 +916,7 @@ class DateField(Field): class TimeField(Field): default_error_messages = { - 'invalid': _('Time has wrong format. Use one of these formats instead: {format}.'), + 'invalid': _("Time has wrong format. Use one of these formats instead: {format}."), } format = api_settings.TIME_FORMAT input_formats = api_settings.TIME_INPUT_FORMATS @@ -972,7 +972,7 @@ class TimeField(Field): class ChoiceField(Field): default_error_messages = { - 'invalid_choice': _('`{input}` is not a valid choice.') + 'invalid_choice': _("`{input}` is not a valid choice.") } def __init__(self, choices, **kwargs): @@ -1016,8 +1016,8 @@ class ChoiceField(Field): class MultipleChoiceField(ChoiceField): default_error_messages = { - 'invalid_choice': _('`{input}` is not a valid choice.'), - 'not_a_list': _('Expected a list of items but got type `{input_type}`.') + 'invalid_choice': _("`{input}` is not a valid choice."), + 'not_a_list': _("Expected a list of items but got type `{input_type}`.") } default_empty_html = [] @@ -1051,7 +1051,7 @@ class FileField(Field): 'invalid': _("The submitted data was not a file. Check the encoding type on the form."), 'no_name': _("No filename could be determined."), 'empty': _("The submitted file is empty."), - '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 @@ -1118,7 +1118,7 @@ class ListField(Field): child = None initial = [] default_error_messages = { - 'not_a_list': _('Expected a list of items but got type `{input_type}`.') + 'not_a_list': _("Expected a list of items but got type `{input_type}`.") } def __init__(self, *args, **kwargs): @@ -1249,7 +1249,7 @@ class ModelField(Field): that do not have a serializer field to be mapped to. """ 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."), } def __init__(self, model_field, **kwargs): diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 7c4d5e958..c7053d8f3 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -125,7 +125,7 @@ class GenericAPIView(views.APIView): try: page = paginator.page(page_number) except InvalidPage as exc: - error_format = _('Invalid page ({page_number}): {message}') + error_format = _("Invalid page ({page_number}): {message}.") raise NotFound(error_format.format( page_number=page_number, message=six.text_type(exc) )) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 7b119291d..3737b21fa 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -128,9 +128,9 @@ class StringRelatedField(RelatedField): class PrimaryKeyRelatedField(RelatedField): default_error_messages = { - 'required': _('This field is required.'), + 'required': _("This field is required."), 'does_not_exist': _("Invalid pk '{pk_value}' - object does not exist."), - 'incorrect_type': _('Incorrect type. Expected pk value, received {data_type}.'), + 'incorrect_type': _("Incorrect type. Expected pk value, received {data_type}."), } def use_pk_only_optimization(self): @@ -152,11 +152,11 @@ class HyperlinkedRelatedField(RelatedField): lookup_field = 'pk' default_error_messages = { - 'required': _('This field is required.'), - 'no_match': _('Invalid hyperlink - No URL match'), - 'incorrect_match': _('Invalid hyperlink - Incorrect URL match.'), - 'does_not_exist': _('Invalid hyperlink - Object does not exist.'), - 'incorrect_type': _('Incorrect type. Expected URL string, received {data_type}.'), + 'required': _("This field is required."), + 'no_match': _("Invalid hyperlink - No URL match."), + 'incorrect_match': _("Invalid hyperlink - Incorrect URL match."), + 'does_not_exist': _("Invalid hyperlink - Object does not exist."), + 'incorrect_type': _("Incorrect type. Expected URL string, received {data_type}."), } def __init__(self, view_name=None, **kwargs): @@ -292,7 +292,7 @@ class SlugRelatedField(RelatedField): default_error_messages = { 'does_not_exist': _("Object with {slug_name}={value} does not exist."), - 'invalid': _('Invalid value.'), + 'invalid': _("Invalid value."), } def __init__(self, slug_field=None, **kwargs): diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 623ed5865..9d7c8884a 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -296,7 +296,7 @@ def get_validation_error_detail(exc): @six.add_metaclass(SerializerMetaclass) class Serializer(BaseSerializer): default_error_messages = { - 'invalid': _('Invalid data. Expected a dictionary, but got {datatype}.') + 'invalid': _("Invalid data. Expected a dictionary, but got {datatype}.") } @property @@ -473,7 +473,7 @@ class ListSerializer(BaseSerializer): many = True default_error_messages = { - 'not_a_list': _('Expected a list of items but got type `{input_type}`.') + 'not_a_list': _("Expected a list of items but got type `{input_type}`.") } def __init__(self, *args, **kwargs): diff --git a/rest_framework/validators.py b/rest_framework/validators.py index e3719b8d5..cf6f07180 100644 --- a/rest_framework/validators.py +++ b/rest_framework/validators.py @@ -19,7 +19,7 @@ class UniqueValidator: Should be applied to an individual field on the serializer. """ - message = _('This field must be unique.') + message = _("This field must be unique.") def __init__(self, queryset, message=None): self.queryset = queryset @@ -73,8 +73,8 @@ class UniqueTogetherValidator: Should be applied to the serializer class, not to an individual field. """ - message = _('The fields {field_names} must make a unique set.') - missing_message = _('This field is required.') + message = _("The fields {field_names} must make a unique set.") + missing_message = _("This field is required.") def __init__(self, queryset, fields, message=None): self.queryset = queryset @@ -152,7 +152,7 @@ class UniqueTogetherValidator: class BaseUniqueForValidator: message = None - missing_message = _('This field is required.') + missing_message = _("This field is required.") def __init__(self, queryset, field, date_field, message=None): self.queryset = queryset @@ -216,7 +216,7 @@ class BaseUniqueForValidator: class UniqueForDateValidator(BaseUniqueForValidator): - message = _('This field must be unique for the "{date_field}" date.') + message = _("This field must be unique for the \"{date_field}\" date.") def filter_queryset(self, attrs, queryset): value = attrs[self.field] @@ -231,7 +231,7 @@ class UniqueForDateValidator(BaseUniqueForValidator): class UniqueForMonthValidator(BaseUniqueForValidator): - message = _('This field must be unique for the "{date_field}" month.') + message = _("This field must be unique for the \"{date_field}\" month.") def filter_queryset(self, attrs, queryset): value = attrs[self.field] @@ -244,7 +244,7 @@ class UniqueForMonthValidator(BaseUniqueForValidator): class UniqueForYearValidator(BaseUniqueForValidator): - message = _('This field must be unique for the "{date_field}" year.') + message = _("This field must be unique for the \"{date_field}\" year.") def filter_queryset(self, attrs, queryset): value = attrs[self.field] diff --git a/rest_framework/versioning.py b/rest_framework/versioning.py index 440efd139..587ba9f13 100644 --- a/rest_framework/versioning.py +++ b/rest_framework/versioning.py @@ -67,7 +67,7 @@ class URLPathVersioning(BaseVersioning): Host: example.com Accept: application/json """ - invalid_version_message = _('Invalid version in URL path.') + invalid_version_message = _("Invalid version in URL path.") def determine_version(self, request, *args, **kwargs): version = kwargs.get(self.version_param, self.default_version) @@ -109,7 +109,7 @@ class NamespaceVersioning(BaseVersioning): Host: example.com Accept: application/json """ - invalid_version_message = _('Invalid version in URL path.') + invalid_version_message = _("Invalid version in URL path.") def determine_version(self, request, *args, **kwargs): resolver_match = getattr(request, 'resolver_match', None) @@ -135,7 +135,7 @@ class HostNameVersioning(BaseVersioning): Accept: application/json """ hostname_regex = re.compile(r'^([a-zA-Z0-9]+)\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$') - invalid_version_message = _('Invalid version in hostname.') + invalid_version_message = _("Invalid version in hostname.") def determine_version(self, request, *args, **kwargs): hostname, seperator, port = request.get_host().partition(':') @@ -157,7 +157,7 @@ class QueryParameterVersioning(BaseVersioning): Host: example.com Accept: application/json """ - invalid_version_message = _('Invalid version in query parameter.') + invalid_version_message = _("Invalid version in query parameter.") def determine_version(self, request, *args, **kwargs): version = request.query_params.get(self.version_param)