2

I have a problem with form errors. I want to change the field name that the form error displays.

models.py

class Sales(models.Model):
    customer = models.ForeignKey("Customer")
    ctype = models.ForeignKey("Customer_type", verbose_name="Customer Type")

forms.py

from django.utils.translation import ugettext_lazy as _
class Sales_form(forms.ModelForm):
    class Meta:
        model = Sales
        fields = ('customer','ctype')
        error_messages = {
            'ctype' : {
                'required' : _("Hey yow! this field is required!")
            }
        }

but the error still returns:

{"ctype": ["Hey yow! this field is required!"]}

What I want is like this

{"Customer Type": ["Hey yow! this field is required!"]}

http://pastebin.com/w6UkjzHF

Community
  • 1
  • 1
aldesabido
  • 1,268
  • 2
  • 17
  • 38

1 Answers1

2

You can specify labels for fields in your Meta like this:

from django.utils.translation import ugettext_lazy as _
class Sales_form(forms.ModelForm):
    class Meta:
        model = Sales
        fields = ('customer','ctype')
        labels = {
            'ctype': _('Customer Type'),
        }
        error_messages = {
            'ctype' : {
                'required' : _("Hey yow! this field is required!")
            }
        }

AFAIK there's no direct way to use model field's verbose_name as form label. You can use _meta attribute though:

myfield = models.IntegerField(label=MyModel._meta.get_field('myfield').verbose_name)

Quite hacky in my taste because you still need to pass fieldname.

And you also can build labels dict with dictionary comprehension:

labels = {f.name: f.verbose_name for f in MyModel._meta.get_fields()}

But be careful with this because get_fields also returns ManyToManyRel which has no attribute verbose_name.

You can refer to render errors part of django docs also, might be helpful.

if you want just change keys in your form.errors dict, you can do this with this approach:

labels = {f.name: f.verbose_name for f in MyModel._meta.get_fields()}
errors_keys = tuple(form.errors.keys())
for k in errors_keys:
    form.errors[labels[k]] = form.errors[k]
    del form.errors[k]

Or just form.errors[labels[k]] = form.errors.pop(k). Also check this question about dict key replacement

Community
  • 1
  • 1
valignatev
  • 6,020
  • 8
  • 37
  • 61
  • Thank you for the response @valen. I tried your answer but the labels doesn't seem to work and the error message is still the same. – aldesabido Jul 16 '16 at 03:47
  • May be I misunderstand your question a little bit. Do you want pretty verbose labels on html page or just replace key in errors dict? – valignatev Jul 16 '16 at 03:52
  • Sorry for that. I just want to replace the key in erros dict. – aldesabido Jul 16 '16 at 05:28