- Author:
- johnboxall
- Posted:
- December 1, 2008
- Language:
- Python
- Version:
- 1.0
- Score:
- 5 (after 5 ratings)
Often I want fields in my models to be unique - Django's unique
works too late in model form validation and will throw an exception unless you check for it by hand. This is a bit of code that cleans up the boiler plate of checking if different fields are unique.
Set exclude_initial
to False
if you want to raise an error if the unique field cannot be set to whatever value the instance had before.
Update
Thanks fnl for rightly pointing out that Django's unique=True
does check for this - just make sure to pass instance=obj
when you're initializing your forms. HOWEVER a problem you'll typically run into with this is though you want a field to unique, you also want multiple entries to be able to be blank
. This can help you!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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')
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
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).
#
Please login first before commenting.