from django import forms
def clean_unique(form, field, exclude_initial=True,
format="The %(field)s %(value)s has already been taken."):
value = form.cleaned_data.get(field)
if value:
qs = form._meta.model._default_manager.filter(**{field:value})
if exclude_initial and form.initial:
initial_value = form.initial.get(field)
qs = qs.exclude(**{field:initial_value})
if qs.count() > 0:
raise forms.ValidationError(format % {'field':field, 'value':value})
return value
# Usage:
class DeployForm(forms.ModelForm):
"""We want both the slug and cname fields to be unique"""
class Meta:
model = Website
fields = ['slug', 'cname']
def clean_slug(self):
return clean_unique(self, 'slug')
def clean_cname(self):
return clean_unique(self, 'cname')
Comments
Django actually supports this problem if you know how, ie the snippet might not really be the right solution:
The whole trick is using the instance parameter when creating the form instance from the post. django will load and know about the unique field, ie the line:
is essential.
#
Whoa, you're right - not sure how I missed that!
#
We can try a little easily method.
On this way we must redefine email-field at all, but we don't need to override init method. This may be useful for remove validation for 'unique' attribute for one or few field (not for all).
#