I'm using Django 1.9.8 and I'm trying to learn how to use form validation. I'm working on a form for registering users. I have 2 problems that I'm stuck on.
The field for re-entering the password isn't accessible (rather, just not there at all) in the forms.py file methods. When I use
raise Exception(self.cleaned_data.get('password'))to view the content, the password is shown. I can also view the username and email. When I do the same for the repassword field, it showsNoneEdit - this was solved by changing the forms.py file to use a clean() methodThe validation errors are not displaying at all on my form. If there are errors the redirect back to the form is working, but there is nothing in the inputs for the user to fix, nor is the error displayed. Edit - solved by changing the RegisterForm call after the else statement to
form = RegisterForm(request.POST)
Here is the forms.py file
#forms.py
class RegisterForm(forms.Form):
username = forms.CharField(label="Username", max_length=30,
widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'}))
email = forms.CharField(label="Email", max_length=30,
widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'email'}))
password = forms.CharField(label="Password", max_length=30,
widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'password', 'type' : 'password'}))
repassword = forms.CharField(label="RePassword", max_length=30,
widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'repassword', 'type' : 'password'}))
#Edit - this was changed to the clean() function in the selected answer.
def clean_password(self):
password1 = self.cleaned_data.get('password')
password2 = self.cleaned_data.get('repassword')
#raise Exception(self.cleaned_data.get('repassword')) # None is displayed
if password1 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return self.cleaned_data
Here's the form template
#register.html
{% if form.errors %}
<h2>ERROR!</h2>
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% endif %}
<form method="post" action="" id="RegisterForm">
{% csrf_token %}
<p class="bs-component">
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.email.label_tag }}</td>
<td>{{ form.email }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
<tr>
<td>{{ form.repassword.label_tag }}</td>
<td>{{ form.repassword }}</td>
</tr>
</table>
</p>
<p class="bs-component">
<center>
<input class="btn btn-success btn-sm" type="submit" value="Register" />
</center>
</p>
<input type="hidden" name="next" value="{{ next }}" />
</form>
Here's the view
#views.py
class RegisterViewSet(viewsets.ViewSet):
#GET requests
def register(self,request):
return render(request, 'authorization/register.html', {'form': RegisterForm})
#POST requests
def create(self,request):
form = RegisterForm(request.POST)
if form.is_valid():
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
user = User.objects.create_user(username,email,password)
user.save()
return HttpResponseRedirect('/users')
else:
return render(request, 'authorization/register.html', {'form': RegisterForm })
#changed the previous line to the following. This fixed the errors not displaying
#return render(request, 'authorization/register.html', {'form': RegisterForm(request.POST) })