Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django error message displayed for unique fields

I would like to change the default error message when duplicate entries try to save when they should be unique i.e. unique=True. Much like this:

email = models.EmailField(unique=True, error_messages={'unique':"This email has already been registered."})

But, unique in the above case was a guess, and doesn't work. Neither can I find out what the name of the error actually is. Does anyone know the correct name?

Note, this validation is model level, not form validation.

EDIT: A bit more info, at the moment the current error message is displayed by form.errors:

[model_name] with this [field_label] already exists

Which isn't very user friendly, so I wanted to override it...

like image 595
Ben Griffiths Avatar asked Apr 01 '11 14:04

Ben Griffiths


3 Answers

Thank you very much.

email = models.EmailField(unique=True, error_messages={'unique':"This email has already been registered."})

this worked very well now.

If you want to customise error_messages like invalided, do it in forms.ModelForm

email = forms.EmailField(error_messages={'invalid': 'Your email address is incorrect'})

But unique message should be customised in model field, as ben mentioned

email = models.EmailField(unique=True, error_messages={'unique':"This email has already been registered."})
like image 123
Stephen Avatar answered Oct 28 '22 16:10

Stephen


This error message is apparently hard-coded in the django/db/models/base.py file.

def unique_error_message(self, model_class, unique_check):
    opts = model_class._meta
    model_name = capfirst(opts.verbose_name)

    # A unique field
    if len(unique_check) == 1:
        field_name = unique_check[0]
        field_label = capfirst(opts.get_field(field_name).verbose_name)
        # Insert the error into the error dict, very sneaky
        return _(u"%(model_name)s with this %(field_label)s already exists.") %  {
            'model_name': unicode(model_name),
            'field_label': unicode(field_label)
        }
    # unique_together
    else:
        field_labels = map(lambda f: capfirst(opts.get_field(f).verbose_name), unique_check)
        field_labels = get_text_list(field_labels, _('and'))
        return _(u"%(model_name)s with this %(field_label)s already exists.") %  {
            'model_name': unicode(model_name),
            'field_label': unicode(field_labels)
        }

One way to solve this is to create your custom model derived from EmailField and override the unique_error_message method. But beware that it might break things when you upgrade to newer versions of Django.

like image 9
mif Avatar answered Oct 28 '22 17:10

mif


Since Django 1.4 the exact example you supply actually works. Maybe they found your error report and just fixed it?

https://github.com/django/django/blob/1.4.20/django/db/models/base.py#L780

like image 3
Emil Stenström Avatar answered Oct 28 '22 16:10

Emil Stenström