Introduction:
In this article I will explain to you how to create a simple Django project with the basic login and logout authentication process. Django has built-in authentication systems and built-in views that you can use to quickly and easily create a user authentication using your own templates.
Create the Django project:
Create a new project in your IDE or Terminal and go to the folder you have created. Create a virtual environment.
Now install the dependencies inside your virtual environment:
pip install django python-decouple ipyhton
You can chain multiple dependencies together. You install Django for your project. python-decouple
is for the .env
file where you put all your secret environment variables, like the SECRET_KEY
or all email configurations, etc. And ipython
is a nice tool for the shell.
After you have successfully installed your dependencies, store them in a file in the root directory with:
pip freeze > requirements.txt
pip freeze
lists all dependencies in terminal
> requirements.txt
this will save all installed dependencies in a the file called requirements.txt
or create the file.
Now build your Django project inside the virtual environment using:
django-admin startproject authentication .
The .
after the name of your project is to create the Django project directory inside the root directory.
After you have created your first application inside the Django project:
python manage.py startapp accounts
The application has to be added into to the INSTALLED_APPS
in the settings.py
file inside the authentication
project directory.
# authentication/settings.py
# Application definition
INSTALLED_APPS = [
"accounts",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
If you want to create your own custom authentication templates, you need to make sure that your created application accounts
is placed before the "django.contrib.admin"
application.
Ensure security of your project:
To ensure the security of your project, you should store the SECRET_KEY
, DEBUG
, ALLOWED_HOSTS
, etc. in a locally stored .env
file.
Enter the above command in your terminal to create a secure SECRET_KEY
:
python manage.py shell -c 'from django.core.management import utils; print(utils.get_random_secret_key())'
Create an .env
file in the root directory and add:
# general project variables:
SECRET_KEY="r^=cy=8w8$^p)!gd6#%*c)s-u4h!ua9r6!i317qt^6l47)94t^"
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
To be able to start your development server, you need to have access to the project variables such as the SECRET_KEY
. You need to make sure that your settings.py
file has access to the environment variables stored in the .env
file.
The first step is already done by installing python-decouple
. Now update the settings.py
file:
# authentication/settings.py
from decouple import config
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config("DEBUG")
ALLOWED_HOSTS = config("ALLOWED_HOSTS", default="").split(",")
ALLOWED_HOSTS
should be a list. We have stored the value as a comma separated string in the .env
file. Within the settings.py
file, we split the comma-separated strings at the ,
and create a list from them.
The next file you need to create is the .gitignore
file, to avoid sending your environment variables to GitHub or GitLab.
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# Django stuff:
*.log
*.pot
*.pyc
# virtual environment
.venv
# IDE
.idea
# Local configuration
.env
This .gitignore
file is just an example, yours may look different depending on your IDE.
Creating a User model:
It is good practice to use the AbstractUser
to create your own user model:
# accounts/models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
If necessary, you can add additional attributes within the User
class.
The next step is to add the User
model to the Admin Panel. This way you can easily create User
instances from the admin panel. You can also create User
instances in the Python shell.
# accounts/models.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
UserModel = get_user_model()
admin.site.register(UserModel, UserAdmin)
In the settings.py
file, we need to set the User
we created to tell the project that we want to use our custom User
model.
# authentication/settings.py
# set the User
AUTH_USER_MODEL = "accounts.User"
The next commands create the migration file inside the accounts
application and create the database tables inside the SQLite database.
python manage.py makemigrations
python manage.py migrate
Now, it is time to create an admin user in terminal:
python manage.py createsuperuser
Username: Admin
Email address: admin@mail.com
Password:
Password (again):
Superuser created successfully.
Remember or save these authentication details for future use.
Setting the authentication URLs and creating custom authentication templates:
The new application was already added to the project when we added the accounts
name to the INSTALLED_APPS
list in settings.py
, but we need to integrate all future url patterns from the accounts
application into the project URL file:
# authentication/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("accounts/", include("accounts.urls", namespace="accounts")),
]
We will include all url patterns of the accounts
application, which will be under the accounts
namespace.
Inside the accounts
application, create a new file called urls.py
and add the following:
# accounts/urls.py
from django.urls import path, include
app_name = "accounts"
urlpatterns = [
path("", include("django.contrib.auth.urls")),
]
The app_name
should be the same as the namespace
attribute inside the path()
function in the authentication urls.py
file.
If you start the development server with:
python manage.py runserver
and navigate to the URL: http://127.0.0.1:8000/accounts/
you will have access to the following URL patterns:
admin/
accounts/ login/ [name='login']
accounts/ logout/ [name='logout']
accounts/ password_change/ [name='password_change']
accounts/ password_change/done/ [name='password_change_done']
accounts/ password_reset/ [name='password_reset']
accounts/ password_reset/done/ [name='password_reset_done']
accounts/ reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/ reset/done/ [name='password_reset_complete']
Let's create a test user and navigate to http://127.0.0.1:8000/admin/
. Enter the username
in my example: Admin and the password
you set with the python manage.py createsuperuser
command.
Under the heading ACCOUNTS
you can add a new user
. You enter the username, twice the password and save it. Then you have to enter additional information such as first and last name and email address and save again.
Login and Logout view:
The first template we will create is the base.html
template in the accounts
application. First create a directory inside the accounts
application called: templates
and inside the templates
directory create a file called base.html
:
<!-- accounts/templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div>
<span class="logo">Authentication</span>
{% if request.user.is_authenticated %}
<ul class="menu">
<li {% if section == "dashboard" %}class="selected"{% endif %}>
<a href="{% url 'accounts:dashboard' %}">My dashboard</a>
</li>
</ul>
{% endif %}
<span class="user">
{% if request.user.is_authenticated %}
Hello {{ request.user.first_name|default:request.user.username }},
<form action="{% url 'accounts:logout' %}" method="post">
<button type="submit">Logout</button>
{% csrf_token %}
</form>
{% else %}
<a href="{% url 'accounts:login' %}">Log-in</a>
{% endif %}
</span>
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
The URL syntax in my case always has the application name accounts
before the URL name, otherwise the URL name will not be found. If the authentication URL is in a namespace, the application name must be added.
We will create three additional templates, a login template, a logged_out template and a template after the user has successfully logged in, a dashboard.
<!-- accounts/templates/registration/login.html -->
{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
<h1>Log-in</h1>
{% if form.errors %}
<p>
Your username and password didn't match.
Please try again.
</p>
{% else %}
<p>
Please, use the following form to log-in.
</p>
{% endif %}
<div class="login-form">
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
<p><input type="submit" value="Log-in"></p>
</form>
</div>
{% endblock %}
<!-- accounts/templates/registration/logged_out.html -->
{% extends "base.html" %}
{% block title %}Logged out{% endblock %}
{% block content %}
<h1>Logged out</h1>
<p>
You have been successfully logged out.
You can <a href="{% url 'accounts:login' %}">log-in again</a>.
</p>
{% endblock %}
Make sure you use the template name: logged_out
otherwise this template will be ignored.
<!-- accounts/templates/dashboard.html -->
{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<h1>Dashboard</h1>
<p>Welcome to your dashboard.</p>
{% endblock %}
It is not done yet. We need to create the view and an URL for the dashboard and set some variables in the settings.py
file.
# accounts/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
@login_required
def dashboard(request):
return render(request, "dashboard.html", {"section": "dashboard"})
Only an authenticated user has access to this view, we ensure this with the login_required
decorator.
# accounts/urls.py
from django.urls import path, include
from accounts.views import dashboard
app_name = "accounts"
urlpatterns = [
path("", include("django.contrib.auth.urls")),
path("", dashboard, name="dashboard"),
]
In settings.py
file we have to set some variable to ensure the redirection after the login to our dashboard URL:
# authentication/settings.py
LOGIN_REDIRECT_URL = "accounts:dashboard"
LOGIN_URL = "login"
LOGOUT_URL = "logout"
The LOGIN_REDIRECT_URL
leads the way to the dashboard URL pattern inside the accounts
application.
-
Django documentation:
-
GitHub repository:
Top comments (0)