Say I have 30 fields in my model where one of them is link
.
I want to throw a specific error when link
is invalid, and I want to change the required
error for all the fields (including link
).
If I write the following form:
class product_prices_form(forms.ModelForm):
class Meta:
error_messages = {"link":{"invalid": "Not really valid"}, #Only change invalid for link-field
"required":"You forgot something here!"} #Change the "required" error for all fields
model = my_model
the required
error is not overwritten. If I move it into the “link” dict, it works fine, but creating that for all the remaining 29 fields i doubt is the right way to do.
I believe (am not 100% certain) that error_messages is an attribute of the fields, not of the form. (That is consistent with the behavior you’re seeing and what I’m seeing in the source.)
I’m guessing the easiest way to do this would be to write a custom clean method that, after calling super().clean()
, iterates through the errors list and change the text of any instance of a required
error.
I don’t think I understand that? If I dont have the link:
first e.g just error_messages = {"invalid": _("not really valid")}
that overwrites all invalid
messages, correct? What I don’t understand if why it cannot be chained
I don’t know, does it? I’m not seeing that from the docs I’m reading - particularly in the modelform_factory method:
error_messages
is a dictionary of model field names mapped to a dictionary of error messages.
and in the Overriding the default fields paragraph:
Similarly, you can specify the labels
, help_texts
and error_messages
attributes of the inner Meta
class if you want to further customize a field.
And if you follow the logic in the source code, you’ll see that error_messages are applied on a per-field basis, not a global form basis. So I would be a bit surprised if it worked the way you’re describing for field-level errors.
(Note: All my comments above are referring to field-level errors. non_field_errors are handled differently.)
1 Like
You can define the error_messages
per field via the ModelForm.Meta
as per this part of the docs. However as Ken said and you’ve discovered, it’s not possible to change this globally, or declare a value to use across all the fields of a form.
That doesn’t mean your stuck redefining this multiple times either. You could do any of the following:
- Subclass
ModelForm
and change the error messages in the __init__
method for all fields.
- Subclass the built-in fields and use those rather than
forms.CharField
, etc.
- Create a function that that returns the dict of error messages, and call that when setting the
error_messages=
parameter of the form fields. forms.CharField(error_messages=custom_messages())
There are probably other options available too, such as customizing the Meta class to allow you to specify a form wide value, but I’m less sure of the work involved.