2010-10-22 3 views
14

В классе Meta модели я определяю unique_together. У меня есть ModelForm, основанный на этой модели. Когда я вызываю is_valid в этом ModelForm, ошибка будет автоматически повышаться, если проверка unique_together завершается с ошибкой. Это все хорошо.Django: Как переопределить сообщение об ошибке unique_together?

Теперь моя проблема в том, что меня не устраивает сообщение об ошибке unique_together по умолчанию. Я хочу переопределить его. Как я могу это сделать? Для связанной с полем ошибки я легко могу это сделать, установив error_messages на параметры поля. Но unique_together - это полевая ошибка. Как я могу переопределить сообщение об ошибке без полей?

+0

Я думаю, вам лучше знак другой ответ, как принято вместо моего, поскольку Django 1.7 внес важные изменения, что также влияет на мой ответ. – FallenAngel

ответ

27

Вы можете сделать this в Django 1,7

from django.forms import ModelForm 
from django.core.exceptions import NON_FIELD_ERRORS 

class ArticleForm(ModelForm): 
    class Meta: 
     error_messages = { 
      NON_FIELD_ERRORS: { 
       'unique_together': "%(model_name)s's %(field_labels)s are not unique.", 
      } 
     } 
+1

выглядит очень сексуально;) – andi

+0

Это еще лучше! –

+1

Важное примечание: вы должны импортировать 'NON_FIELD_ERRORS' из' django.core.exceptions'. –

1

После быстрой проверки, кажется, что unique_together ошибки проверки жестко закодированы глубоко в django.db.models.Model.unique_error_message:

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) 
     } 

Так может быть, вы должны попытаться переопределить этот метод от вашей модели, чтобы вставить свое сообщение!?

Однако, я не пробовал, и это кажется довольно жестоким решением! Но если у вас нет чего-то лучшего, вы можете попробовать ...

+1

Да, он жестко закодирован. Ненавидеть это. Команда django должна была принять во внимание сценарий, в котором разработчик переопределяет невольное сообщение об ошибке. –

0

Примечание: С этого ответа многое изменилось в Django. Так что лучше проверить другие ответы ...

Если то, что sebpiq истинно (так как я не проверить исходный код), то есть один из возможных решений вы можете сделать, но это трудный путь ...

вы можете определить правило проверки в вашей форме, as it described here

вы можете увидеть examples валидации с более чем одной областью, поэтому с помощью этого метода можно определить уникальную вместе проверить перед стандартным Джанго уникальная проверки выполняется ...

Или худший, вы можете сделать валидацию в своем v перед тем, как вы попытаетесь сохранить объекты ...

+0

это больше не относится к Django> = 1.7 – nuts

-1

Вы можете взглянуть на переопределение django/db/models/base.py:Model._perform_unique_checks() в вашей модели.

В этом методе вы можете получить «оригинальную» ошибку:

errors = super(MyModel, self)._perform_unique_checks(unique_checks) 

- то изменить и вернуть их вверх.

+0

Очень опасно переопределять «частные» методы, подобные этому. Вы никогда не знаете, когда они могут измениться или даже исчезнуть. – richard

24

Update 2016/10/20: Смотрите jifeng-yin «S даже лучше ответ ниже Джанго> = 1,7

Самое ценное способ переопределить эти сообщения об ошибках могут быть переопределить unique_error_message метод на вашей модели. Django вызывает этот метод, чтобы получить сообщение об ошибке всякий раз, когда он сталкивается с проблемой уникальности во время проверки.

Вы можете просто обрабатывать конкретный случай вы хотите, и пусть все остальные случаи будут обрабатываться Django как обычно:

def unique_error_message(self, model_class, unique_check): 
    if model_class == type(self) and unique_check == ('field1', 'field2'): 
     return 'My custom error message' 
    else: 
     return super(Project, self).unique_error_message(model_class, unique_check) 
+0

Это соответствует решению, которое я видел в [блоге] (http://chriskief.com/2013/11/20/customize-djangos-unique_together-error-message/). Но у меня есть вопрос ... почему нам нужно проверить, есть ли 'model_class' типа' self'? – HorseloverFat

+0

Это не самый «самый приятный» способ. по крайней мере, для Django> = 1.7. См. Ответ @ jifeng.yin – nuts