From f1c615ecd69a3e06e057c7192a9fd985abcbe55e Mon Sep 17 00:00:00 2001 From: James Tanner Date: Tue, 19 Mar 2024 15:51:09 -0400 Subject: [PATCH] Handle date placeholders in error messages too. Signed-off-by: James Tanner --- rest_framework/exceptions.py | 15 ++++++++++++--- tests/test_validation_error.py | 1 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py index e41afeec7..1f6d80cd9 100644 --- a/rest_framework/exceptions.py +++ b/rest_framework/exceptions.py @@ -149,7 +149,7 @@ class ValidationError(APIException): status_code = status.HTTP_400_BAD_REQUEST default_detail = _('Invalid input.') default_code = 'invalid' - default_params = SafeReplacerDict() + default_params = {} def __init__(self, detail=None, code=None, params=None): if detail is None: @@ -162,7 +162,7 @@ class ValidationError(APIException): # For validation failures, we may collect many errors together, # so the details should always be coerced to a list if not already. if isinstance(detail, str): - detail = [detail % params] + detail = [self.template_detail(detail, params)] elif isinstance(detail, ValidationError): detail = detail.detail elif isinstance(detail, (list, tuple)): @@ -171,13 +171,22 @@ class ValidationError(APIException): if isinstance(detail_item, ValidationError): final_detail += detail_item.detail else: - final_detail += [detail_item % params if isinstance(detail_item, str) else detail_item] + final_detail += [self.template_detail(detail_item, params) if isinstance(detail_item, str) else detail_item] detail = final_detail elif not isinstance(detail, dict) and not isinstance(detail, list): detail = [detail] self.detail = _get_error_details(detail, code) + def template_detail(self, detail, params): + """Handle error messages with templates and placeholders.""" + try: + return detail % params + except KeyError: + return detail + except ValueError: + return detail + class ParseError(APIException): status_code = status.HTTP_400_BAD_REQUEST diff --git a/tests/test_validation_error.py b/tests/test_validation_error.py index 34f382414..cc9d7f25f 100644 --- a/tests/test_validation_error.py +++ b/tests/test_validation_error.py @@ -164,7 +164,6 @@ class TestValidationErrorWithDjangoStyle(TestCase): params={'value3': '44'} ) assert isinstance(error.detail, list) - import pdb; pdb.set_trace() assert len(error.detail) == 3 assert str(error.detail[0]) == 'Invalid value: 42' assert str(error.detail[1]) == 'Invalid value: 43'