2015-03-10 1 views
3

J'ai créé un modèle appelé terme et un validateur pour cela, comme ceci:validation du modèle sur la mise à jour dans django

from django.db import models 
from django.contrib.auth.models import User 
from django.core.exceptions import ValidationError 


def validate_insensitive_exist(value): 
      exists = Term.objects.filter(word__iexact = value.lower()).exists() 
      if exists == True: 
        raise ValidationError("This term already exist.") 


class Term(models.Model): 
     word = models.CharField(max_length=200, unique=True, validators=[validate_insensitive_exist]) 
     related_term = models.ManyToManyField("self", null=True, blank=True) 
     def __unicode__(self): 
       return self.word 
     def natural_key(self): 
       return self.word 

Qu'est-ce que ce validateur n'est de soulever une exception lorsque je tente d'ajouter un terme existe déjà (en majuscule ou en minuscule), et cela fonctionne bien. Mon problème est que quand j'essaye d'éditer un terme existant (juste pour mettre un caractère en majuscule ou minuscule - mais le mot est le même), une exception est levée parce qu'en fait j'essaye d'ajouter un mot qui existe déjà, être lui-même. Ce que je veux, c'est valider le nouveau mot que j'entre dans tous les autres termes, en ignorant le mot qui était en premier lieu et que je suis en train de changer.

Quelqu'un peut-il m'aider avec ça?

+0

double possible (http://stackoverflow.com/questions/20564856/django-exclude-self-from-queryset-for-validation) – rnevius

+1

[django excluent l'auto de queryset pour la validation] Ce n'est pas vraiment un dupliquer - cette question utilisait déjà une méthode 'clean'. Pour répondre à cette question, vous devez d'abord expliquer pourquoi un validateur ne va pas travailler. – Alasdair

+0

Exactement Alasdair. Je veux faire la validation dans le validateur et ne pas faire comme dans la méthode clean. – Falcoa

Répondre

1

Vous ne pouvez pas utiliser un validateur pour cela, car un validateur a uniquement accès à la valeur, et non à l'instance de modèle que vous essayez de valider.

Vous pouvez définir une méthode clean pour votre modèle et exclure l'instance actuelle du jeu de requêtes.

class Term(models.Model): 
    word = models.CharField(max_length=200, unique=True) 
    related_term = models.ManyToManyField("self", null=True, blank=True) 


    def clean(self): 
     other_terms = Term.objects.filter(word__iexact=self.word.lower()) 
     if self.pk: 
      other_terms = other_terms.exclude(pk=self.pk) 
     if other_terms.exists(): 
      raise ValidationError("This term already exists.")