2010-10-22 13 views
14

En la clase Meta de un modelo, defino un unique_together. Tengo un ModelForm basado en este modelo. Cuando llamo is_valid en este ModelForm, se generará automáticamente un error si falla la validación unique_together. Eso está bien.Django: ¿Cómo anular el mensaje de error unique_together?

Ahora mi problema es que no estoy satisfecho con el mensaje de error unique_together predeterminado. Quiero anularlo. ¿Cómo puedo hacer eso? Para un error relacionado con el campo, puedo hacerlo fácilmente estableciendo error_messages en los parámetros del campo. Pero unique_together es un error no de campo. ¿Cómo puedo anular un mensaje de error que no sea de campo?

+0

os adivina mejor marca otra respuesta como aceptada en lugar de la mía ya que Django 1.7 hizo cambios importantes que también afectan mi respuesta. – FallenAngel

Respuesta

27

Usted puede hacer this en 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

se ve muy sexy;) – andi

+0

¡Eso es aún mejor! –

+1

Una nota importante: debe importar 'NON_FIELD_ERRORS' de' django.core.exceptions'. –

1

Después de una comprobación rápida, parece que unique_together errores de validación están codificadas de profundidad en 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) 
     } 

Así que tal vez debería tratar de reemplazar este método de su modelo, para insertar su propio mensaje!?

Sin embargo, no lo he intentado, ¡y parece una solución bastante brutal! Pero si no tiene algo mejor, puede intentar ...

+1

Sí, está codificado. Lo odio. El equipo de django debería haber tenido en cuenta la situación del desarrollador al anular el mensaje de error no de campo. –

0

Aviso: Mucho ha cambiado en Django desde esta respuesta. Así que es mejor consultar otras respuestas ...

Si lo sebpiq es cierto (ya que yo no consultar el código fuente), entonces no es una solución posible que puede hacer, pero es la forma más dura ...

se puede definir una regla de validación en su forma, as it described here

se puede ver examples de validación con más de un campo, por lo que mediante el uso de este método, se puede definir un único conjunto comprobar antes de ejecutar Django patrón de control única ...

O el peor, puede hacer una validación en su v Antes de intentar guardar los objetos ...

+0

esto ya no es cierto para Django> = 1.7 – nuts

-1

Puede echar un vistazo a la anulación de django/db/models/base.py:Model._perform_unique_checks() en su modelo.

En ese método se puede obtener los errores "originales":

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

- a continuación, modificar y devolverlos hacia arriba.

+0

Es muy arriesgado anular métodos "privados" como este. Nunca se sabe cuándo podrían cambiar o incluso desaparecer – richard

24

actualización 20/10/2016: Ver jifeng-yin 's incluso más agradable respuesta por debajo de Django> = 1,7

La manera más agradable para anular estos mensajes de error podría ser la de sustituir el método unique_error_message en su modelo. Django llama a este método para obtener el mensaje de error cada vez que encuentra un problema de exclusividad durante la validación.

justo Usted puede manejar el caso específico que desee y dejar que todos los demás casos serán manejados por Django como de costumbre:

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

Esto coincide con una solución que vi publicada en un [blog] (http://chriskief.com/2013/11/20/customize-djangos-unique_together-error-message/). Pero tengo una pregunta ... ¿por qué tenemos que comprobar si 'model_class' es de tipo' self'? – HorseloverFat

+0

, esta no es realmente la forma "más bonita". al menos para Django> = 1.7. Ver la respuesta de @ jifeng.yin – nuts

Cuestiones relacionadas