Reputation: 1609
I am using the django User model with profile to extend the User with few more attributes. I require to ensure unique email id across the users in the User table.
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.admin import UserAdmin
class UserForm(UserAdmin):
class Meta:
model = User
fields = "__all__"
readonly_fields = ('date_joined',)
def clean_email(self):
email = self.cleaned_data.get('email')
if email and User.objects.filter(email=email).exists():
raise forms.ValidationError(u'Email addresses must be unique.')
return email
This validation message is not displayed in the User form.
The custom user admin is defined as
class CustomUserAdmin(UserAdmin):
def save(UserForm, commit=True):
return super(UserForm, self).save(commit=False)
if User.objects.filter(email=email).exists():
raise forms.ValidationError(_("Email already exists ya"),
code='invalid')
inlines = (ProfileInline, )
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
This validation message is seen in the traceback in debug mode and not in the UserForm.
Require the message to show the error in the UserForm. I understand that there are 2 forms viz. UserCreationForm, UserChangeForm in the django auth.
Using django 3.0, python 3.7
Upvotes: 0
Views: 1069
Reputation: 542
You can create your custom validator and provide it as "validators" argument in the Field Creation.
Here is the custom validator:
from django.core.exceptions import ValidationError
def email_validator(email):
if User.objects.filter(email=email).exists():
raise ValidationError("Email already exists ya", code='invalid')
And then in the User model's email field just provide this email_validator in the validators argument as below:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# other fields
email = models.EmailField("email", unique=True, validators=[email_validator])
Django will use your custom validator and it will show the error right below the field on the User Creation Form.
Upvotes: 0
Reputation: 1
Instead of using clean_email, try using clean . Ex:
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.admin import UserAdmin
class UserForm(UserAdmin):
class Meta:
model = User
fields = "__all__"
readonly_fields = ('date_joined',)
def clean(self):
cleaned_data = super().clean()
email = cleaned_data.get('email')
if email and User.objects.filter(email=email).exists():
raise forms.ValidationError(u'Email addresses must be unique.')
Upvotes: 0
Reputation: 334
If I where you I would put a unique = True on the email field on your user model. Django will then take care of the rest, no custom form validation necessary.
Upvotes: 0
Reputation: 3457
You should use clean method in Model class instead. Add this code into your User(you should customize auth's User model) in models.py.
from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ValidationError
class User(AbstractUser):
# add clean method here
def clean(self):
if User.objects.filter(email=email).exists():
raise ValidationError(_("Email already exists ya"), code='invalid')
This method is for validating field of model.
Upvotes: 6