Django表单中的唯一模型字段验证

Django表单中的唯一模型字段验证,django,django-forms,Django,Django Forms,我有一个带有几个独特字段的模型,我正在为它编写一个表单。我找到了一些对[validate\u unique][1]方法的引用,调用该方法时应该检查字段的唯一性,但我的表单.is\u valid()始终返回True 我的测试用例: class ServerFormTest( TestCase ): def setUp( self ): self.server = Server.objects.create( host = "127.0.0.1", name = "local

我有一个带有几个独特字段的模型,我正在为它编写一个表单。我找到了一些对
[validate\u unique][1]
方法的引用,调用该方法时应该检查字段的唯一性,但我的表单
.is\u valid()
始终返回
True

我的测试用例:

class ServerFormTest( TestCase ):
    def setUp( self ):
        self.server = Server.objects.create( host = "127.0.0.1", name = "localhost" )

    def test_unique_name(self):
        form = ServerForm({
            'name': 'localhost',
            'host': '127.0.0.1'
        })

        self.assertFalse( form.is_valid( ) )
我的表格:

class ServerForm( forms.ModelForm ):
    class Meta:
        model = Server
        fields = ('name', 'host')

    def clean( self ):
        self.validate_unique()
        return self.cleaned_data
服务器型号:

class Server( models.Model ):
    host = models.GenericIPAddressField( blank = False, null = False, unique = True )
    name = models.CharField( blank = False, null = False, unique = True, max_length = 55 )
是一种
模型
方法

运行超类
clean
方法应注意给定
ModelForm
的模型唯一性检查

class MyModelForm(forms.ModelForm):    
    def clean(self):
        cleaned_data = super(MyModelForm, self).clean()
        # additional cleaning here
        return cleaned_data

django文档中有一个关于在
ModelForm
s上重写clean的特别说明,它会自动执行几个模型验证步骤。

我通过将
validate\u unique()
添加到
save()


它对我有用。我不知道你的情况。

实现字段唯一性的简单方法是在模型字段中使用“unique=True”。例如:

email = models.EmailField(verbose_name=_('Email'), max_length=255, unique=True)

phone = models.CharField(verbose_name=_('Phone Number'), max_length=14, unique=True)
但是,如果您真的想通过表单实现这一点,或者情况需要它,例如,在上面的代码部分中,这里的电话号码是一个字符字段。这里很难实现唯一性,因为对于系统0171-xxxxxxx和0171xxxxxxx是不同的数字,但实际上它们是相同的。它可以通过表单的clean_phone方法轻松验证。这里,在检查唯一性之前,从字符串(字符字段)解析数字

    def clean_phone(self):
        phone = self.cleaned_data.get("phone")
        # parse digits from the string
        digit_list = re.findall("\d+", phone)
        phone = ''.join(digit_list)
        
        if CustomUser.objects.filter(phone=phone).exists():
            raise forms.ValidationError("phone number is already exists")
        return phone


你也可以发布你的
服务器
模型吗?当你编辑时,你在代码块的最后一行有一个缩进故障^^@spectras被当场捕获!
    def clean_phone(self):
        phone = self.cleaned_data.get("phone")
        # parse digits from the string
        digit_list = re.findall("\d+", phone)
        phone = ''.join(digit_list)
        
        if CustomUser.objects.filter(phone=phone).exists():
            raise forms.ValidationError("phone number is already exists")
        return phone