Django Custom Authentication | Registration, Login, Logout, ResetPassword, UserProfile And AdminProfile
Start a project
django-admin startproject registrationForm
Project directory
registration/settings.py
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
# Used for authentication
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Custom app
'enroll',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
# Used for authentication
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
# Used for authentication
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
registration/urls.py
from django.contrib import admin
from django.urls import path
from enroll import views
urlpatterns = [
path('admin/', admin.site.urls),
path('signup/', views.sign_up, name='signup'),
path('login/', views.user_login, name='login'),
path('profile/', views.user_profile, name='profile'),
path('logout/', views.user_logout, name='logout'),
path('changepassword/', views.user_change_password,
name='changepassword'),
path('changepassword2/', views.user_change_password2,
name='changepassword2'),
path('userdetail/<int:id>', views.user_detail,
name='userdetail'),
]
enroll/forms.py
from django.contrib.auth.models import User
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class SignUpForm(UserCreationForm):
password2 = forms.CharField(label='Confirm Password (again)',
widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email']
labels = {'email': 'Email'}
class EditUserProfileForm(UserChangeForm):
password = None
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email',
'date_joined', 'last_login']
labels = {'email': 'Email'}
class EditAdminProfileForm(UserChangeForm):
password = None
class Meta:
model = User
fields = '__all__'
labels = {'email': 'Email'}
enroll/views.py
from django.shortcuts import render, HttpResponseRedirect
from .forms import SignUpForm, EditUserProfileForm, \
EditAdminProfileForm
from django.contrib import messages
from django.contrib.auth.forms import AuthenticationForm, \
PasswordChangeForm, SetPasswordForm, UserChangeForm
from django.contrib.auth import authenticate, login, logout, \
update_session_auth_hash
from django.contrib.auth.models import User
def sign_up(request):
if request.method == "POST":
fm = SignUpForm(request.POST)
if fm.is_valid():
messages.success(request, 'Account created successfully')
fm.save()
return HttpResponseRedirect('/login/')
else:
fm = SignUpForm()
return render(request, 'enroll/signup.html', {'form': fm})
def user_login(request):
if not request.user.is_authenticated:
if request.method == "POST":
fm = AuthenticationForm(request=request, data=request.POST)
if fm.is_valid():
user_name = fm.cleaned_data['username']
user_password = fm.cleaned_data['password']
user = authenticate(username=user_name, password=user_password)
if user is not None:
login(request, user)
messages.success(request, 'Logged in successfully !!')
return HttpResponseRedirect('/profile/')
else:
fm = AuthenticationForm()
return render(request, 'enroll/userlogin.html', {'form': fm})
else:
return HttpResponseRedirect('/profile/')
def user_profile(request):
if request.user.is_authenticated:
if request.method == "POST":
if request.user.is_superuser == True:
fm = EditAdminProfileForm(request.POST, instance=request.user)
users = User.objects.all()
else:
fm = EditUserProfileForm(request.POST, instance=request.user)
users = None
if fm.is_valid():
messages.success(request, 'Profile updated')
fm.save()
else:
if request.user.is_superuser == True:
fm = EditAdminProfileForm(instance=request.user)
users = User.objects.all()
else:
fm = EditUserProfileForm(instance=request.user)
users = None
return render(request, 'enroll/profile.html',
{'name': request.user.username, 'form': fm, 'users': users})
else:
return HttpResponseRedirect('/login/')
def user_logout(request):
logout(request)
return HttpResponseRedirect('/login/')
# Change password with old password
def user_change_password(request):
if request.user.is_authenticated:
if request.method == "POST":
fm = PasswordChangeForm(user=request.user, data=request.POST)
if fm.is_valid():
fm.save()
# Update user session
update_session_auth_hash(request, fm.user)
messages.success(request, 'Password changed successfully')
return HttpResponseRedirect('/profile/')
else:
fm = PasswordChangeForm(user=request.user)
return render(request, 'enroll/changePassword.html', {'form': fm})
else:
return HttpResponseRedirect('/login/')
# Change password without old password
def user_change_password2(request):
if request.user.is_authenticated:
if request.method == "POST":
fm = SetPasswordForm(user=request.user, data=request.POST)
if fm.is_valid():
fm.save()
# Update user session
update_session_auth_hash(request, fm.user)
messages.success(request, 'Password changed successfully')
return HttpResponseRedirect('/profile/')
else:
fm = SetPasswordForm(user=request.user)
return render(request, 'enroll/changePassword2.html', {'form': fm})
else:
return HttpResponseRedirect('/login/')
def user_detail(request, id):
if request.user.is_authenticated:
pi = User.objects.get(pk=id)
fm = EditAdminProfileForm(instance=pi)
return render(request, 'enroll/userdetail.html',
{'name': request.user.username,'form': fm})
else:
return HttpResponseRedirect('/login/')
templates/signup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration form</title>
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<style>
/* Custom styles if needed */
body {
}
.custom-form {
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.success {
color: green;
}
</style>
</head>
<body>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6 custom-form">
<form action="" method="post" novalidate class="needs-validation">
{% csrf_token %}
{% for fm in form %}
<div class="form-group">
{{ fm.label_tag }}
{{ fm }}
<small class="text-danger">{{ fm.errors|striptags }}</small>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">SignUp</button>
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="er">{{error}}</p>
{% endfor %}
{% endif %}
</form>
<br>
<!-- <a class="btn btn-outline-primary" href="{% url 'login' %}">Login</a> -->
{% if messages %}
{% for message in messages %}
<small class="d-block mt-2 {% if message.tags %}{{ message.tags }}{% endif %}">{{ message }}</small>
{% endfor %}
{% endif %}
</div>
</div>
</div>
<!-- Include Bootstrap JS and Popper.js (optional) -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>
templates/uselogin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User login</title>
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<style>
body {
}
.login-container {
max-width: 400px;
margin: auto;
padding: 20px;
margin-top: 100px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.er {
color: red;
}
</style>
</head>
<body>
<div class="login-container">
<form action="" method="post" novalidate>
{% csrf_token %}
{% for fm in form %}
<div class="form-group">
{{ fm.label_tag }}
{{ fm }}
<small class="form-text text-danger">{{ fm.errors|striptags }}</small>
</div>
{% endfor %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="er">{{ error }}</p>
{% endfor %}
{% endif %}
<button type="submit" class="btn btn-primary">Login</button>
</form>
<br>
<!-- <a class="btn btn-outline-primary" href="{% url 'signup' %}">SignUp</a> -->
</div>
<!-- Include Bootstrap JS and Popper.js (optional) -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>
templates/profile.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User profile</title>
<!-- Bootstrap CSS link (make sure to include it) -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="jumbotron">
<div style=" padding: 20px; color: #fff; border-radius: 10px;">
<h2 class="display-4 text-sm mt-2" style="font-size: 2.5rem;font-weight: bold;">User Profile</h2>
<h5 style="color: #ecf0f1;">Welcome {{name}}</h5>
{% if users != None %}
<h5 style="color: #ecf0f1;">List of users</h5>
{% for user in users %}
<a href="{% url 'userdetail' user.id %}" style="color: #ffffff;">{{user.username}}</a><br>
{% endfor %}
{% endif %}
</div><br>
{% if messages %}
{% for message in messages %}
<div class="alert {% if message.tags %} alert-{{message.tags}}" {% endif %} role="alert">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form action="" method="post">
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p>{{error}}</p>
{% endfor %}
{% endif %}
{% for fm in form %}
{{ fm.label_tag }} {{ fm }} {{ fm.errors|striptags }}<br><br>
{% endfor %}
<input type="submit" value="Save" class="btn btn-primary">
</form><br>
<a class="btn btn-primary" href="{% url 'changepassword' %}">Change Password</a>
<a class="btn btn-primary" href="{% url 'changepassword2' %}">Change Password2</a>
<a class="btn btn-primary" href="{% url 'logout' %}">Logout</a>
</div>
</div>
<!-- Bootstrap JS and Popper.js (optional) -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
templates/changepassword.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Change Password</title>
</head>
<body class="bg-light">
<form action="" method="post" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p>{{error}}</p>
{% endfor %}
{% endif %}
{% for fm in form %}
{{ fm.label_tag }} {{ fm }} {{ fm.errors|striptags }}<br><br>
{% endfor %}
<input type="submit" value="Save">
</form><br><br>
<a href="{% url 'logout' %}">Logout</a><br><br>
<a href="{% url 'profile' %}">Profile</a><br><br>
</body>
</html>
templates/changepassword2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Change Password</title>
</head>
<body class="bg-light">
<form action="" method="post" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p>{{error}}</p>
{% endfor %}
{% endif %}
{% for fm in form %}
{{ fm.label_tag }} {{ fm }} {{ fm.errors|striptags }}<br><br>
{% endfor %}
<input type="submit" value="Save">
</form><br><br>
<a href="{% url 'logout' %}">Logout</a><br><br>
<a href="{% url 'profile' %}">Profile</a><br><br>
</body>
</html>
templates/userdetail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Detail</title>
<!-- Bootstrap CSS link (make sure to include it) -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="jumbotron" style=" color: #fff; padding: 20px; border-radius: 10px;">
<h3 class="display-4 text-sm mt-2 font-weight-bold" style="font-size: 2.5rem;">User Profile</h3>
<h3 style="font-size: 1.5rem;">Welcome {{name}}</h3>
</div>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div class="mt-3">
<a class="btn btn-primary" href="{% url 'profile' %}">Profile</a>
<a class="btn btn-primary" href="{% url 'logout' %}">Logout</a>
</div>
</div>
<!-- Bootstrap JS and Popper.js (optional) -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Perform migration
python manage.py makemigrations
python manage.py migrate
Run server
python manage.py runserver
Output
User registration
User login
User profile
User details
Chane password with old password
Chane password without old password
Show and update user profile
Django Login Form
Django Login