19

I know how to set my own custom error messages when using ordinary Django Forms. But what about Django Form based on an existing model? Consider following model and form:

Class MyModel(models.Model):
    name = models.CharField(max_length='30')

Class MyForm(forms.ModelForm):
    Class Meta:
        model = MyModel

If I create such form and try to post it, message "This field is required" appears. But how to change it? Of course I could do something like this:

Class MyForm(forms.ModelForm):
    model = forms.CharField(error_messages = {'required': "something..."})
    Class Meta:
        model = MyModel

But according to the documentation, max_length attribute won't be preserved and I have to write it explicitly to the form definition. I thought that the purpose of Model Forms is to avoid writing the same code twice. So there has to be some easy way to change the custom error message without rewriting the whole form. Basically it would be enough for me if my message looked something like "The field 'name' is required".

Please help.

tobik
  • 7,098
  • 7
  • 41
  • 53

2 Answers2

48
class MyForm(forms.ModelForm):
    class Meta:
            model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['name'].error_messages = {'required': 'custom required message'}

        # if you want to do it to all of them
        for field in self.fields.values():
            field.error_messages = {'required':'The field {fieldname} is required'.format(
                fieldname=field.label)}
yprez
  • 14,854
  • 11
  • 55
  • 70
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Thank you, that looks good. However I got the impression that you did avoid writing the same code twice but by writing some another code which is actually longer and uglier ;) Nevertheless it will spare some work at least on large forms, so thanks again. – tobik Mar 21 '11 at 23:45
  • I guess to each his own. If you need to replace all `required` messages, this is cleanest by far. I also don't think it's longer, unless you count the __init__ call, which I generally use in everything. – Yuji 'Tomita' Tomita Mar 22 '11 at 02:03
  • 2
    Note that you will get [a mysterious `KeyError`](http://stackoverflow.com/questions/7463159/django-form-is-valid-keeps-throwing-keyerror) if you get an `invalid` error and don't supply a message for it. – Dan Abramov Sep 18 '11 at 18:26
  • It might just be a typo error but there is a `:` (colon) at the end of the line `super(MyForm, self).__init__(self, *args, **kwargs):` This was giving me an error. When I removed this colon, although my model is validated but I get an error in the template that `MyForm` object has no attribute `get`. If I remove this code then it works perfectly fine. Please help – Sachin Jan 09 '12 at 12:41
  • @Sachin, yes, I'd be very careful when copy and pasting code - it's often **pseudo code**. That said, I don't see a `get` call in here - you should ask a new question with the django tag :) – Yuji 'Tomita' Tomita Jan 09 '12 at 17:52
  • 3
    @Dan yep I got exactly that mysterious KeyError. The line `field.error_messages['required'] ='The field {fieldname} is required'.format(fieldname=field.label)` would work better I think. – fpghost Jun 15 '14 at 21:11
  • 2
    Didn't work for me it still to occur "Please fill out this field" :( – ePascoal May 13 '15 at 13:29
  • Thank you Bro You are a life saver _/\\_ – Muthu Kumar Dec 08 '17 at 12:48
  • Just check that field.label exists to avoid that error – AppHandwerker Oct 03 '20 at 10:47
-1

you can change field attributes at runtime, in the __init__ method.

Jerzyk
  • 3,662
  • 23
  • 40