I have a model with a few unique fields and I'm writing a form for it. I found some reference to the [validate_unique][1]
method that should check for uniqueness on fields when you call it but my form .is_valid()
always returns True
.
My testcase:
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( ) )
and my form:
class ServerForm( forms.ModelForm ):
class Meta:
model = Server
fields = ('name', 'host')
def clean( self ):
self.validate_unique()
return self.cleaned_data
server model:
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 )
validate_unique is a Model
method.
Running the superclass clean
method should take care of model uniqueness checks given a ModelForm
.
class MyModelForm(forms.ModelForm):
def clean(self):
cleaned_data = super(MyModelForm, self).clean()
# additional cleaning here
return cleaned_data
There is a warning on the django docs specifically about overriding clean on ModelForm
s, which automatically does several model validation steps.
simple way to achieve uniqueness to a field, just use "unique=True" in the model field. Example:
email = models.EmailField(verbose_name=_('Email'), max_length=255, unique=True)
phone = models.CharField(verbose_name=_('Phone Number'), max_length=14, unique=True)
But if you really want to achieve this through form, or situation demands it, for example, in the above code section, here phone number is a character field. uniqueness is difficult to achieve here because for the system 0171-xxxxxxx and 0171xxxxxxx are different numbers but actually they are same. It can be easily validated through form's clean_phone method. Here the digit is parsed from the string(character field) before checking uniqueness.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With