在Django中进行更新的模型验证 [英] Model validation on update in django

查看:96
本文介绍了在Django中进行更新的模型验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个名为Term的模型,并为其创建了一个验证器,如下所示:

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

当我尝试添加一个已经存在(小写或大写)的术语时,此验证器的作用是引发异常,并且它工作正常.我的问题是,当我尝试编辑现有术语(只是将一个字符以大写或小写形式-但单词相同)时,会引发一个异常,因为实际上我是在尝试添加一个已经存在的单词,本身.我想要的是对照所有其他术语来验证我输入的新单词,而忽略了最初出现的单词以及我实际上正在更改的单词.

有人可以帮我吗?

解决方案

您不能为此使用验证器,因为验证器只能访问该值,而不能访问您要验证的模型实例. /p>

您可以定义 clean 方法用于您的模型,并从查询集中排除当前实例.

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.")

I've created a model called Term and a validator for it, like this:

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

What this validator does is to raise an exception when I try to add a term that already exists (in lower or uppercase), and it's working fine. My problem is that when I try to edit an existing term (just to put a character in upper or lowercase - but the word is the same), an exception is raised because in fact i'm trying to add a word that already exists, being itself. What I want is to validate the new word that I enter against all the other terms, ignoring the word that was in the first place and that I'm actually changing.

Can anyone help me with that?

解决方案

You can't use a validator for this, because a validator only has access to the value, not to the model instance that you are trying to validate.

You can define a clean method for your model, and exclude the current instance from the queryset.

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.")

这篇关于在Django中进行更新的模型验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆