Reputation:
According to https://docs.djangoproject.com/en/dev/ref/forms/validation/
# Good
ValidationError(
_('Invalid value: %(value)s'),
params={'value': '42'},
)
# Bad
ValidationError(_('Invalid value: %s') % value)
The docs doesnt really explain why it is bad / good. Can someone give a concrete example?
Furthermore, when I inspect form.errors
, I get something like 'Invalid: %(value)s'
. How do I get the params from the Validation error and interpolate them into the error msg?
Edited
So is this considered good?
ValidationError(
_('Invalid value: %(value)s') % {'value': '42'},
)
I think the real question is: why pass the variables separately via the params
argument? Why not interpolate directly into the error msg (ignore named or positional interpolation for now)???
Edited
Ok, From the source @ https://github.com/django/django/blob/stable/1.5.x/django/forms/forms.py I don't think there is any way to retrieve ValidationError's params since the Form does not even save the ValidationError object itself. See code below.
class ValidationError(Exception):
"""An error while validating data."""
def __init__(self, message, code=None, params=None):
import operator
from django.utils.encoding import force_text
"""
ValidationError can be passed any object that can be printed (usually
a string), a list of objects or a dictionary.
"""
if isinstance(message, dict):
self.message_dict = message
# Reduce each list of messages into a single list.
message = reduce(operator.add, message.values())
if isinstance(message, list):
self.messages = [force_text(msg) for msg in message]
else:
self.code = code
self.params = params
message = force_text(message)
self.messages = [message]
class Form:
....
def _clean_fields(...):
....
except ValidationError as e:
self._errors[name] = self.error_class(e.messages) # Save messages ONLY
if name in self.cleaned_data:
del self.cleaned_data[name]
Upvotes: 8
Views: 6793
Reputation: 6162
ValidationError
is caught by the form validation routine and though it can just show a message, it's better to save the possibility of getting params
of error; eg. field name, value that caused error and so on. It's stated just before the example you've provided.
In order to make error messages flexible and easy to override
Upvotes: 2
Reputation: 308779
If you have multiple parameters, they might appear in a different order when you translate the error message.
Named arguments allow you to change the order in which the arguments appear, without changing params
. With a tuple of arguments, the order is fixed.
Note that you are linking to the development version of the Django docs. The validation error is not interpolating the parameters because you are using Django 1.5 or earlier. If you try your code in the 1.6 beta, then the parameters are interpolated into the error message.
Upvotes: 3