Django. POST request after reloading a page. Sign up form
Question:
When user enters incorrect data in form, he gets errors. If after that user reloads a page, he gets the same page, the same form with the same fields, errors. I don’t know why after reloading a page request is POST.
Every time after sending form, when I reload page with form I send a POST request.
views.py
from django.shortcuts import render
from django.shortcuts import render, redirect
from .forms import LogInForm, SignUpForm
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.hashers import make_password
from django.contrib.auth import authenticate, logout, login as auth_login
from django.contrib import messages
import os
import shutil
# Create your views here.
@login_required
def index(request):
return render(request, 'index.html')
def login(request):
logInForm = LogInForm()
if request.method == 'POST':
form = LogInForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(
username=cd['username'], password=cd['password'])
if user is not None:
auth_login(request, user)
return redirect("main")
else:
messages.error(request, "Invalid login or password")
return redirect('login')
else:
form = LogInForm()
else:
return render(request, 'logIn.html', {"form": logInForm})
def signUp(request):
def createFolder(username):
toFolder = "jsons/" + username
fromFolder = "scripts/"
os.mkdir(toFolder)
toFolder = "jsons/" + username + '/scripts'
os.mkdir(toFolder)
os.mkdir("jsons/" + username + "/messages")
if (os.path.exists(fromFolder) and os.path.exists(toFolder)):
for file in os.listdir(fromFolder):
if os.path.isfile(os.path.join(fromFolder, file)):
shutil.copy(os.path.join(fromFolder, file),
os.path.join(toFolder, file))
if os.path.isdir(os.path.join(fromFolder, file)):
os.system(f'rd /S /Q {toFolder}/{file}')
shutil.copytree(os.path.join(fromFolder, file),
os.path.join(toFolder, file))
with open(toFolder + '/config.ini', 'w') as file:
file.write('[Telegram]n')
file.write('[VK]n')
file.write('[INST]n')
file.write('[WA]n')
signUpForm = SignUpForm()
if (request.method == 'POST'):
form = SignUpForm(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
user.password = make_password('password')
user.save()
auth_login(request, user)
createFolder(user.username)
return redirect("main")
else:
return render(request, 'signUp.html', {"form": form})
else:
return render(request, 'signUp.html', {"form": signUpForm})
def logout_view(request):
logout(request)
return redirect('login')
@login_required
def profile(request):
current_user = request.user
username = current_user.username
email = current_user.email
phoneNumber = current_user.phoneNumber
content = {
'username': username,
'email': email,
'phoneNumber': phoneNumber,
}
return render(request, 'profile.html', context=content)
forms.py
from django.forms import ModelForm
from django import forms
from .models import User
class LogInForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(
attrs={'placeholder': 'Username', 'class': 'form-input'}), required=True)
password = forms.CharField(widget=forms.PasswordInput(
attrs={'placeholder': 'Password', 'class': 'form-input'}), required=True, min_length=8)
class SignUpForm(ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput(
attrs={"placeholder": "Password"}), min_length=8, required=True)
password2 = forms.CharField(
label='Confirm password', widget=forms.PasswordInput(attrs={"placeholder": "Confirm password"}), min_length=8, required=True)
error_css_class = 'message-error'
error_messages = {
'password_mismatch': 'Passwords must match.',
}
class Meta:
model = User
fields = ('username', 'email', 'phoneNumber', 'password')
widgets = {
"username": forms.TextInput(
attrs={
"placeholder": "Username"
}
),
"email": forms.TextInput(
attrs={
"placeholder": "Email"
}
),
"phoneNumber": forms.TextInput(
attrs={
"placeholder": "Phone number (with a country code) ",
"type": "tel",
"minlength": 12,
"maxlength": 12,
},
),
}
def clean(self):
cleaned_data = super(SignUpForm, self).clean()
password = self.cleaned_data.get("password")
confirm_password = self.cleaned_data.get("password2")
if password and confirm_password:
if password != confirm_password:
self.add_error(None, "Passwords don't match")
ifNums = False
ifLets = False
for letter in password:
if letter.isalpha():
ifLets = True
if letter.isdigit():
ifNums = True
if ifNums == True and ifLets == True:
break
if ifNums == False or ifLets == False:
self.add_error("password","Your password must contain at least one digit and one letter!")
return cleaned_data
signUp.html
<!DOCTYPE html>
{% load static %}
<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">
<link rel="stylesheet" href="{% static "css/signUp.css" %}" />
<title>Sign up</title>
</head>
<body>
<div class="container">
<form class="form" method="post" action="{% url 'signUp' %}">
<h1 class="title">Sign up</h1>
{% csrf_token %}
{% for field in form %}
{{ field }}
{% if field.errors %}
{% for error in field.errors %}
<span class="message-error"> {{ error }} </span>
{% endfor %}
{% endif %}
{% endfor %}
{% if form.non_field_errors %}
{% for non_field_error in form.non_field_errors %}
<span class="message-error"> {{ non_field_error }} </span>
{% endfor %}
{% endif %}
<label for="confirm-valid" class="label-check">
<input type="checkbox" id="confirm-valid" required> I've checked the correctness of the entered data
</label>
<label for="confirm-agreement" class="label-check">
<input type="checkbox" id="confirm-agreement" required> I agree with the user agreement
</label>
<button class="form-button" type="submit">Sign up</button>
</form>
</div>
</body>
</html>
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, AbstractUser
# Create your models here.
class User(AbstractUser):
username = models.CharField(max_length=100, unique=True, error_messages={
'unique': "This username has already been registered."})
password = models.CharField(max_length=200, unique=False)
email = models.EmailField(unique=True, error_messages={
'unique': "This email has already been registered."})
phoneNumber = models.CharField(max_length=12, unique=True, error_messages={
'unique': "This phone number has already been registered."})
first_name = None
last_name = None
I need my form to work this way:
User enters correct data – he goes to main page.
User enters incorrect data – he gets the form with errors, but after reloading the page, form have to be clean.
EDIT
signUp view
signUpForm = SignUpForm()
if (request.method == 'POST'):
form = SignUpForm(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
user.password = make_password('password')
user.save()
auth_login(request, user)
createFolder(user.username)
return redirect("main")
else:
return redirect('signUp')
return render(request, 'signUp.html', {"form": signUpForm})
else:
return redirect('main')
If I make sign up view like this, it works. But after reloading I get form without errors. How can I make it so that the form after reloading in this way will be with errors?
Answers:
Yes it can be done, the form will be rendered as it is, if you don’t create a fresh form variable everytime.
remove the line SignUpForm=SignUpForm()
.
if (request.method == 'POST'):
form = SignUpForm(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
user.password = make_password('password')
user.save()
auth_login(request, user)
createFolder(user.username)
return redirect("main")
else:
form = SignUpForm()
return render(request, 'signUp.html', {"form": form})
similarly, in login
view,
def login(request):
if request.method == 'POST':
form = LogInForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(
username=cd['username'], password=cd['password'])
if user is not None:
auth_login(request, user)
return redirect("main")
else:
messages.error(request, "Invalid login or password")
else:
form = LogInForm()
return render(request, 'logIn.html', {"form": form})
When user enters incorrect data in form, he gets errors. If after that user reloads a page, he gets the same page, the same form with the same fields, errors. I don’t know why after reloading a page request is POST.
Every time after sending form, when I reload page with form I send a POST request.
views.py
from django.shortcuts import render
from django.shortcuts import render, redirect
from .forms import LogInForm, SignUpForm
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.hashers import make_password
from django.contrib.auth import authenticate, logout, login as auth_login
from django.contrib import messages
import os
import shutil
# Create your views here.
@login_required
def index(request):
return render(request, 'index.html')
def login(request):
logInForm = LogInForm()
if request.method == 'POST':
form = LogInForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(
username=cd['username'], password=cd['password'])
if user is not None:
auth_login(request, user)
return redirect("main")
else:
messages.error(request, "Invalid login or password")
return redirect('login')
else:
form = LogInForm()
else:
return render(request, 'logIn.html', {"form": logInForm})
def signUp(request):
def createFolder(username):
toFolder = "jsons/" + username
fromFolder = "scripts/"
os.mkdir(toFolder)
toFolder = "jsons/" + username + '/scripts'
os.mkdir(toFolder)
os.mkdir("jsons/" + username + "/messages")
if (os.path.exists(fromFolder) and os.path.exists(toFolder)):
for file in os.listdir(fromFolder):
if os.path.isfile(os.path.join(fromFolder, file)):
shutil.copy(os.path.join(fromFolder, file),
os.path.join(toFolder, file))
if os.path.isdir(os.path.join(fromFolder, file)):
os.system(f'rd /S /Q {toFolder}/{file}')
shutil.copytree(os.path.join(fromFolder, file),
os.path.join(toFolder, file))
with open(toFolder + '/config.ini', 'w') as file:
file.write('[Telegram]n')
file.write('[VK]n')
file.write('[INST]n')
file.write('[WA]n')
signUpForm = SignUpForm()
if (request.method == 'POST'):
form = SignUpForm(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
user.password = make_password('password')
user.save()
auth_login(request, user)
createFolder(user.username)
return redirect("main")
else:
return render(request, 'signUp.html', {"form": form})
else:
return render(request, 'signUp.html', {"form": signUpForm})
def logout_view(request):
logout(request)
return redirect('login')
@login_required
def profile(request):
current_user = request.user
username = current_user.username
email = current_user.email
phoneNumber = current_user.phoneNumber
content = {
'username': username,
'email': email,
'phoneNumber': phoneNumber,
}
return render(request, 'profile.html', context=content)
forms.py
from django.forms import ModelForm
from django import forms
from .models import User
class LogInForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(
attrs={'placeholder': 'Username', 'class': 'form-input'}), required=True)
password = forms.CharField(widget=forms.PasswordInput(
attrs={'placeholder': 'Password', 'class': 'form-input'}), required=True, min_length=8)
class SignUpForm(ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput(
attrs={"placeholder": "Password"}), min_length=8, required=True)
password2 = forms.CharField(
label='Confirm password', widget=forms.PasswordInput(attrs={"placeholder": "Confirm password"}), min_length=8, required=True)
error_css_class = 'message-error'
error_messages = {
'password_mismatch': 'Passwords must match.',
}
class Meta:
model = User
fields = ('username', 'email', 'phoneNumber', 'password')
widgets = {
"username": forms.TextInput(
attrs={
"placeholder": "Username"
}
),
"email": forms.TextInput(
attrs={
"placeholder": "Email"
}
),
"phoneNumber": forms.TextInput(
attrs={
"placeholder": "Phone number (with a country code) ",
"type": "tel",
"minlength": 12,
"maxlength": 12,
},
),
}
def clean(self):
cleaned_data = super(SignUpForm, self).clean()
password = self.cleaned_data.get("password")
confirm_password = self.cleaned_data.get("password2")
if password and confirm_password:
if password != confirm_password:
self.add_error(None, "Passwords don't match")
ifNums = False
ifLets = False
for letter in password:
if letter.isalpha():
ifLets = True
if letter.isdigit():
ifNums = True
if ifNums == True and ifLets == True:
break
if ifNums == False or ifLets == False:
self.add_error("password","Your password must contain at least one digit and one letter!")
return cleaned_data
signUp.html
<!DOCTYPE html>
{% load static %}
<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">
<link rel="stylesheet" href="{% static "css/signUp.css" %}" />
<title>Sign up</title>
</head>
<body>
<div class="container">
<form class="form" method="post" action="{% url 'signUp' %}">
<h1 class="title">Sign up</h1>
{% csrf_token %}
{% for field in form %}
{{ field }}
{% if field.errors %}
{% for error in field.errors %}
<span class="message-error"> {{ error }} </span>
{% endfor %}
{% endif %}
{% endfor %}
{% if form.non_field_errors %}
{% for non_field_error in form.non_field_errors %}
<span class="message-error"> {{ non_field_error }} </span>
{% endfor %}
{% endif %}
<label for="confirm-valid" class="label-check">
<input type="checkbox" id="confirm-valid" required> I've checked the correctness of the entered data
</label>
<label for="confirm-agreement" class="label-check">
<input type="checkbox" id="confirm-agreement" required> I agree with the user agreement
</label>
<button class="form-button" type="submit">Sign up</button>
</form>
</div>
</body>
</html>
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, AbstractUser
# Create your models here.
class User(AbstractUser):
username = models.CharField(max_length=100, unique=True, error_messages={
'unique': "This username has already been registered."})
password = models.CharField(max_length=200, unique=False)
email = models.EmailField(unique=True, error_messages={
'unique': "This email has already been registered."})
phoneNumber = models.CharField(max_length=12, unique=True, error_messages={
'unique': "This phone number has already been registered."})
first_name = None
last_name = None
I need my form to work this way:
User enters correct data – he goes to main page.
User enters incorrect data – he gets the form with errors, but after reloading the page, form have to be clean.
EDIT
signUp view
signUpForm = SignUpForm()
if (request.method == 'POST'):
form = SignUpForm(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
user.password = make_password('password')
user.save()
auth_login(request, user)
createFolder(user.username)
return redirect("main")
else:
return redirect('signUp')
return render(request, 'signUp.html', {"form": signUpForm})
else:
return redirect('main')
If I make sign up view like this, it works. But after reloading I get form without errors. How can I make it so that the form after reloading in this way will be with errors?
Yes it can be done, the form will be rendered as it is, if you don’t create a fresh form variable everytime.
remove the line SignUpForm=SignUpForm()
.
if (request.method == 'POST'):
form = SignUpForm(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
user.password = make_password('password')
user.save()
auth_login(request, user)
createFolder(user.username)
return redirect("main")
else:
form = SignUpForm()
return render(request, 'signUp.html', {"form": form})
similarly, in login
view,
def login(request):
if request.method == 'POST':
form = LogInForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(
username=cd['username'], password=cd['password'])
if user is not None:
auth_login(request, user)
return redirect("main")
else:
messages.error(request, "Invalid login or password")
else:
form = LogInForm()
return render(request, 'logIn.html', {"form": form})