Why my form isn't valid in view whatever I type in?
I am trying to create authentication app with form and it isn't working. I have put some print functions in my view and it prints post and than not valid. I want to click submit button which would trigger post request and view would create new user.
view.py
def index(request):
form = forms.RegisterForm()
context = {
'form': form
}
if request.POST:
print('post')
if form.is_valid():
print('valid')
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password')
account = authenticate(email=email, password=raw_password)
print('authenticate')
login(request, account)
return redirect('home')
else:
print('not valid')
context['registration_form'] = form
else:
form = forms.RegisterForm()
context['registration_form'] = form
return render(request, 'index.html', context)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
</body>
</html>
forms.py
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import ReadOnlyPasswordHashField
User = get_user_model()
class RegisterForm(forms.ModelForm):
"""
The default
"""
full_name = forms.CharField(max_length=30)
password = forms.CharField(widget=forms.PasswordInput)
password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email']
def clean_email(self):
'''
Verify email is available.
'''
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean(self):
'''
Verify both passwords match.
'''
cleaned_data = super().clean()
full_name = cleaned_data.get('full_name')
password = cleaned_data.get("password")
password_2 = cleaned_data.get("password_2")
if password is not None and password != password_2:
self.add_error("password_2", "Your passwords must match")
return cleaned_data
class UserAdminCreationForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
password = forms.CharField(widget=forms.PasswordInput)
password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email']
def clean(self):
'''
Verify both passwords match.
'''
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_2 = cleaned_data.get("password_2")
if password is not None and password != password_2:
self.add_error("password_2", "Your passwords must match")
return cleaned_data
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ['email', 'password', 'is_active', 'admin']
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
If you want me to post anything else just write in the comments
You didn't recieve form's data
in your view with Post
request.
This should fix it:
def index(request):
#first goes get request and it creates blank form
if request.method == "GET":
form = forms.RegisterForm()
context = {
'form': form
}
return render(request, 'index.html', context)
# second, from get request goes post request with data inside
elif request.method == "POST":
#at this line you recieve forms data with request.POST
form = forms.RegisterForm(request.POST)
#and here you validate it
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password')
account = authenticate(email=email, password=raw_password)
print('authenticate')
login(request, account)
return redirect('home')
else:
print('not valid')
context['registration_form'] = forms.RegisterForm()
return render(request, 'index.html', context)
This line would fix your code:
form = forms.RegisterForm(request.POST)
If you add it before if form.is_valid():
(but I also edited your code (not necessary)).