From 03bc732b5c542cf1ab3d4a556651954bf54b9427 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Sat, 6 Oct 2018 17:29:50 +0100 Subject: [PATCH] Populate error.message with error.params Exceptions like ValidationError can include an optional 'params' argument that contains parameters to format the 'message' argument with. Handle these. Signed-off-by: Stephen Finucane Fixes: 78febd1 ("Rework validation, add queryset filter method (#788)") --- django_filters/utils.py | 3 ++- tests/test_utils.py | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/django_filters/utils.py b/django_filters/utils.py index 781d3f436..53e29bcb4 100644 --- a/django_filters/utils.py +++ b/django_filters/utils.py @@ -317,7 +317,8 @@ def translate_validation(error_dict): from rest_framework.exceptions import ValidationError, ErrorDetail exc = OrderedDict( - (key, [ErrorDetail(e.message, code=e.code) for e in error_list]) + (key, [ErrorDetail( + e.message % (e.params or {}), code=e.code) for e in error_list]) for key, error_list in error_dict.as_data().items() ) diff --git a/tests/test_utils.py b/tests/test_utils.py index 2d89a9a54..e944ec427 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -8,7 +8,7 @@ from django.utils.functional import Promise from django.utils.timezone import get_default_timezone -from django_filters import FilterSet +from django_filters import FilterSet, ModelMultipleChoiceFilter from django_filters.exceptions import FieldLookupError from django_filters.utils import ( MigrationNotice, @@ -511,6 +511,13 @@ class Meta: model = Article fields = ['id', 'author', 'name'] + class G(FilterSet): + author = ModelMultipleChoiceFilter(queryset=User.objects.all()) + + class Meta: + model = Article + fields = ['id', 'author', 'name'] + def test_error_detail(self): f = self.F(data={'id': 'foo', 'author': 'bar', 'name': 'baz'}) exc = translate_validation(f.errors) @@ -520,6 +527,15 @@ def test_error_detail(self): 'author': ['Select a valid choice. That choice is not one of the available choices.'], }) + f = self.G({'author': ['bar', 'baz']}) + exc = translate_validation(f.errors) + + # NOTE(stephenfin): Because we can't guarantee the order than filters + # are evaluated, we don't use 'assertDictEqual' here + self.assertEqual(set(exc.detail.keys()), {'author', }) + self.assertRegex(str(exc.detail['author'][0]), + '"ba[rz]" is not a valid value for a primary key.') + def test_full_error_details(self): f = self.F(data={'id': 'foo', 'author': 'bar', 'name': 'baz'}) exc = translate_validation(f.errors)