robos85
robos85

Reputation: 2554

Problem with validating ModelForm

I use ModelForm to create my form. All works fine except 1 thing - validating the unique field. Code:

class Article(models.Model):
...
title = models.CharField(max_length=255, unique=True, error_messages={'max_length' : 'max translation',
                                                                                                    'unique' : 'unique translation',
                                                                                                    'required' : 'req translation',})
...

class ArticleForm(ModelForm):
...
title = forms.CharField(max_length=255, min_length=3, error_messages={'required' : 'req translation',
                                                                                             'min_length' : 'min translation',
                                                                                             'max_length' : 'max translation',
                                                                                             'unique' : 'unique translation',}) 

But when I save my form with non-unique title I don't get my custom translated error but I get default error. How to fix it, that my unique field error is displayed?

EDIT: I found, I think, very convenient way to do that. Maybe someone will use it:)

def unique_error_message(self, model_class, unique_check):
    if 'put_field_name_here' in unique_check and len(unique_check) == 1:
        return 'Here goes a custom unique error'

    return super(Article, self).unique_error_message(model_class, unique_check)

Upvotes: 1

Views: 232

Answers (1)

Alexander Lebedev
Alexander Lebedev

Reputation: 6044

There's no unique key for customizing validation messages. I'd say it's not worth it to customize, but if you must, following approach should help:

import re
class ArticleForm(ModelForm):
    def clean(self, *args, **kwargs):
       result = super(ArticleForm, self).clean(*args, **kwargs)
       if self.non_field_errors:
           for i,msg in enumerate(self.non_field_errors):
               if re.match("^.+ already exists\.$", msg):
                   self.errors["__all__"][i] = custom_msg # Put your own text here
       return result

This solution relies on undocumented internals of Django, but it should do the trick for now. Again, my recommendation is to stick with default.

Upvotes: 1

Related Questions