I'm new to Django so excuse some errors. I'm trying to create validation system for email and print those errors, if any, to the template. Just to make clear, I'm able to create new user and redirect to login page, I just can't display error messages. I do apologize if this is trivial question, but I'm kinda stuck on this for 2 days. I have tried this video on youtube: and i have tried to follow this post and it didn't work.
forms.py
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms
# This class will overwrite origginal UserCreationForm0
class CreateUserForm(UserCreationForm):
email = forms.EmailField(required = True)
class Meta:
model = User
# this will add email to our register_form
fields = [
'username',
'email',
'password1',
'password2'
]
def clean(self):
cleaned_data = super(CreateUserForm, self).clean()
email = self.cleaned_data.get('email')
if User.objects.filter(email=email).exists():
raise forms.ValidationError('User with same email already exists')
return cleaned_data
views.py
from django.shortcuts import render, redirect
from .forms import CreateUserForm
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.forms import AuthenticationForm
from django.contrib import messages
# Create your views here.
def registration_page(request):
if request.user.is_authenticated:
return redirect('')
else:
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'User has been successefly registered, Please Log In!')
return redirect('accounts:login')
else:
CreateUserForm()
context = {
'form': form
}
return render(request, 'accounts/register.html', context)
register.html
<form class="form-horizontal" method="post">
{% csrf_token %}
<div class="form-group">
<label for="email" class="cols-sm-2 control-label">Your Email</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope fa" aria-hidden="true"></i></span>
{{form.email}}
</div>
</div>
</div>
<div class="form-group">
<label for="username" class="cols-sm-2 control-label">Username</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-users fa" aria-hidden="true"></i></span>
{{form.username}}
</div>
</div>
</div>
<div class="form-group">
<label for="password" class="cols-sm-2 control-label">Password</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock fa-lg" aria-hidden="true"></i></span>
{{form.password1}}
</div>
</div>
</div>
<div class="form-group">
<label for="confirm" class="cols-sm-2 control-label">Confirm Password</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock fa-lg" aria-hidden="true"></i></span>
{{form.password2}}
</div>
</div>
</div>
<p>{{form.email.errors}}</p>
<p>{{form.password.errors}}</p>
<div class="form-group ">
<input type="submit" value="Register" class="btn btn-primary btn-lg btn-block login-button">
</div>
<div class="login-register">
<a href="{% url 'accounts:login' %}">Login</a>
</div>
</form>
Errors raised by the clean
method that do not have a field attached, are added to the .non_field_errors()
[Django-doc]. You thus should render these with:
<p>{{ form.non_field_errors }}</p>
<p>{{ form.username.errors }}</p>
<p>{{ form.email.errors }}</p>
<p>{{ form.password1.errors }}</p>
<p>{{ form.password2.errors }}</p>
That being said, (1) this error is field-specific, so you better clean this in the clean_email
method; and (2) Django model forms can check uniqness if the model field is marked as unique.
class CreateUserForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = [
'username',
'email',
'password1',
'password2'
]
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.exclude(pk=self.instance.pk).filter(email=email).exists():
raise forms.ValidationError('User with same email already exists')
return email
Here the .exclude(…)
is useful if the form has a wrapped instance that is already saved in the database.