Skip to content

Commit

Permalink
Populate error.message with error.params
Browse files Browse the repository at this point in the history
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 <stephen@that.guru>
Fixes: 78febd1 ("Rework validation, add queryset filter method (carltongibson#788)")
  • Loading branch information
stephenfin committed Oct 6, 2018
1 parent 552c35a commit 03bc732
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
3 changes: 2 additions & 1 deletion django_filters/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
)

Expand Down
18 changes: 17 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 03bc732

Please sign in to comment.