Demystifying Django: Building Your First Simple Login System

Hello there, aspiring web developers! Have you ever visited a website and noticed a “Login” button or a “Register” link? That’s part of a login system, a fundamental feature for many websites. It allows users to create accounts, secure their information, and access personalized content.

Today, we’re going to dive into the world of Django, a powerful and popular Python web framework, to build our very own simple login system. Don’t worry if you’re new to web development or Django; we’ll break down each step with simple explanations.

What is Django?

Imagine you’re building a house. Instead of starting from scratch with every single brick and nail, you use pre-made components like window frames, doors, and plumbing systems. Django is like that for web development. It’s a “framework” that provides ready-to-use tools and structures to help you build web applications much faster and more efficiently. It handles many of the repetitive tasks so you can focus on the unique parts of your project.

One of Django’s superpowers is its “batteries-included” philosophy, meaning it comes with many features built-in, including a robust authentication system perfect for handling user logins and registrations.

Let’s get started!

Setting Up Your Django Project

Before we write any code, we need to set up our development environment and create a new Django project.

1. Prerequisites

Make sure you have Python installed on your computer. You can download it from the official Python website. Once Python is installed, you’ll also have pip, which is Python’s package installer.

First, let’s create a dedicated folder for our project and navigate into it.

mkdir my_login_project
cd my_login_project

It’s a good practice to use a “virtual environment” for your Python projects. This keeps the packages (libraries) for each project separate, preventing conflicts.

python -m venv venv

(Explanation: python -m venv venv creates a new virtual environment named venv in your current directory.)

Now, activate your virtual environment:

  • On macOS/Linux:
    bash
    source venv/bin/activate
  • On Windows:
    bash
    venv\Scripts\activate

    You’ll see (venv) appear at the beginning of your terminal prompt, indicating that the virtual environment is active.

2. Install Django

With your virtual environment active, install Django using pip:

pip install Django

(Explanation: pip install Django downloads and installs the Django framework into your active virtual environment.)

3. Create a New Django Project

Now, let’s create our Django project. We’ll call it login_site.

django-admin startproject login_site .

(Explanation: django-admin startproject login_site . creates a new Django project named login_site in the current directory. The . at the end means “create it here” instead of creating another subfolder.)

4. Create a Django App

Within our project, we’ll create an “app” to handle our login-related logic. Django projects are made up of one or more apps, which are like small, self-contained modules for specific functionalities (e.g., a “blog” app, a “users” app, etc.). Let’s call our app users.

python manage.py startapp users

(Explanation: python manage.py startapp users creates a new Django application named users within your login_site project.)

5. Register the App

For Django to know about our new users app, we need to tell it about it. Open the login_site/settings.py file and add 'users' to the INSTALLED_APPS list.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users', # Add your new app here
]

(Explanation: INSTALLED_APPS is a list of all Django applications that are active in your project. By adding 'users', we make Django aware of our users app.)

Django’s Built-in Authentication System

One of Django’s greatest strengths is its ready-to-use authentication system. It comes with models (for user data), views (for handling login/logout logic), and templates (for displaying login forms) already set up!

1. Run Migrations

Django needs to set up the necessary database tables for its authentication system (and other built-in features). We do this by running “migrations.”

python manage.py migrate

(Explanation: python manage.py migrate applies all pending database changes (migrations) for the installed apps, creating tables for users, sessions, and more.)

2. Create a Superuser

A superuser is an administrative user who can access the Django admin panel. This is useful for managing users and other data directly.

python manage.py createsuperuser

Follow the prompts to create a username, email, and password.

3. Test the Admin Panel

Let’s quickly check if everything is working. Start the Django development server:

python manage.py runserver

Open your web browser and go to http://127.0.0.1:8000/admin/. You should see a login page. Use the superuser credentials you just created to log in. If you see the admin interface, congratulations! Django’s authentication system is up and running.

Defining URLs for Login and Logout

Now, we need to tell Django which web addresses (URLs) should trigger our login and logout functionalities.

1. Project-level urls.py

Open login_site/urls.py and add a path for our users app’s URLs.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('users.urls')), # Include URLs from our users app
]

(Explanation: path('', include('users.urls')) tells Django that for any URL starting from the root of our site (''), it should look for further URL patterns inside the urls.py file of our users app.)

2. App-level urls.py

Now, let’s create a new file users/urls.py (if it doesn’t exist) and define the login and logout URL patterns there. Django’s auth module provides pre-built views for this.

from django.urls import path
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
]

(Explanation:
* path('login/', ...): This creates a URL /login/.
* auth_views.LoginView.as_view(...): This is Django’s built-in login view.
* template_name='users/login.html': We tell the view which HTML file to use for displaying the login form.
* name='login': This gives a shortcut name to this URL, so we can refer to it as ‘login’ instead of typing out /login/.)

Creating Login and Logout Templates

Django’s built-in LoginView and LogoutView are great, but they need an HTML template to know what to display to the user.

First, create a new folder structure inside your users app: users/templates/users/.

my_login_project/
├── login_site/
│   ├── settings.py
│   ├── urls.py
│   └── ...
├── users/
│   ├── templates/
│   │   └── users/
│   │       ├── login.html
│   │       └── logout.html
│   └── ...
└── manage.py

1. login.html

Create a file named login.html inside users/templates/users/.

<!-- users/templates/users/login.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <style>
        body { font-family: sans-serif; margin: 20px; }
        .form-container { max-width: 400px; margin: auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; box-shadow: 2px 2px 10px rgba(0,0,0,0.1); }
        .form-container h2 { text-align: center; color: #333; }
        .form-container p { margin-bottom: 15px; }
        .form-container label { display: block; margin-bottom: 5px; font-weight: bold; }
        .form-container input[type="text"],
        .form-container input[type="password"] {
            width: calc(100% - 22px); /* Account for padding and border */
            padding: 10px;
            margin-bottom: 15px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .form-container button {
            background-color: #007bff;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            width: 100%;
            font-size: 16px;
        }
        .form-container button:hover { background-color: #0056b3; }
        .errorlist { color: red; list-style-type: none; padding: 0; margin-top: -10px; margin-bottom: 10px;}
        .errorlist li { margin-bottom: 5px; }
    </style>
</head>
<body>
    <div class="form-container">
        <h2>Login</h2>
        <form method="post">
            {% csrf_token %}
            <!-- CSRF Token: Cross-Site Request Forgery (CSRF) is a type of malicious exploit.
                 Django requires this token in all POST forms to protect your site. -->

            {% if form.errors %}
                <p style="color: red;">Your username and password didn't match. Please try again.</p>
            {% endif %}

            <p>
                <label for="{{ form.username.id_for_label }}">Username:</label>
                <input type="text" name="{{ form.username.name }}" id="{{ form.username.id_for_label }}" required>
            </p>
            <p>
                <label for="{{ form.password.id_for_label }}">Password:</label>
                <input type="password" name="{{ form.password.name }}" id="{{ form.password.id_for_label }}" required>
            </p>
            <button type="submit">Login</button>
        </form>
    </div>
</body>
</html>

(Explanation:
* {% csrf_token %}: This is a vital security feature in Django. It prevents a type of attack called Cross-Site Request Forgery. Always include it in your forms!
* {% if form.errors %}: This checks if there are any errors (like wrong username/password) and displays a message.
* form.username.id_for_label, form.username.name, etc.: Django’s LoginView automatically provides a form object in the template context, which we can use to render the input fields easily.)

2. logout.html

Create a file named logout.html inside users/templates/users/.

<!-- users/templates/users/logout.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Logged Out</title>
    <style>
        body { font-family: sans-serif; margin: 20px; text-align: center; }
        .message-container { max-width: 400px; margin: auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; box-shadow: 2px 2px 10px rgba(0,0,0,0.1); }
        .message-container h2 { color: #333; }
        .message-container p { margin-bottom: 20px; }
        .message-container a {
            background-color: #007bff;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            text-decoration: none;
            font-size: 16px;
        }
        .message-container a:hover { background-color: #0056b3; }
    </style>
</head>
<body>
    <div class="message-container">
        <h2>You have been logged out!</h2>
        <p>Thank you for visiting.</p>
        <a href="{% url 'login' %}">Log in again</a>
    </div>
</body>
</html>

(Explanation: This simple template just confirms that the user has been logged out and provides a link to log back in using the {% url 'login' %} template tag, which refers to the URL we named ‘login’ in users/urls.py.)

Creating a Simple Welcome Page and Protecting It

Let’s create a basic welcome page that only logged-in users can see.

1. Update users/views.py

Open users/views.py and add a simple view for our welcome page. We’ll use the @login_required decorator to protect it.

from django.shortcuts import render
from django.contrib.auth.decorators import login_required


@login_required
def home(request):
    return render(request, 'users/home.html')

2. Update users/urls.py

Add a URL pattern for our new home view.

from django.urls import path
from django.contrib.auth import views as auth_views
from . import views # Import the views from the current app

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
    path('', views.home, name='home'), # Our new home page URL
]

(Explanation: We added path('', views.home, name='home'), which makes our welcome page the default page when visiting the root of our site (/).)

3. Create home.html

Create a file named home.html inside users/templates/users/.

<!-- users/templates/users/home.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Welcome!</title>
    <style>
        body { font-family: sans-serif; margin: 20px; text-align: center; }
        .welcome-container { max-width: 600px; margin: auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; box-shadow: 2px 2px 10px rgba(0,0,0,0.1); }
        .welcome-container h1 { color: #28a745; }
        .welcome-container p { margin-bottom: 20px; font-size: 1.1em; }
        .welcome-container a {
            background-color: #dc3545;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            text-decoration: none;
            font-size: 16px;
        }
        .welcome-container a:hover { background-color: #c82333; }
        .welcome-container span { font-weight: bold; color: #007bff; }
    </style>
</head>
<body>
    <div class="welcome-container">
        <h1>Welcome, {% if user.is_authenticated %}<span style="color: green;">{{ user.username }}</span>{% else %}Guest{% endif %}!</h1>
        <p>You have successfully accessed the protected content.</p>
        <p>This page is only visible to logged-in users.</p>
        <a href="{% url 'logout' %}">Logout</a>
    </div>
</body>
</html>

(Explanation:
* {% if user.is_authenticated %}: This template tag checks if the current user is logged in.
* {{ user.username }}: If logged in, it displays the username of the current user.
* {% url 'logout' %}: Provides a link to the logout page.)

Trying It Out!

Make sure your Django development server is running (python manage.py runserver).

  1. Go to http://127.0.0.1:8000/.
  2. You should be automatically redirected to http://127.0.0.1:8000/login/ because our home view requires authentication.
  3. Enter the username and password for the superuser you created earlier.
  4. If successful, you’ll be redirected to http://127.0.0.1:8000/, displaying your welcome message!
  5. Click the “Logout” button, and you’ll be taken to the logout confirmation page.

Congratulations! You’ve just built a simple, yet functional, login system using Django’s powerful built-in authentication.

Next Steps

This is just the beginning. You could enhance your login system by:

  • Adding a registration page: Allow new users to sign up.
  • Password reset functionality: Help users recover forgotten passwords.
  • Better styling: Make your pages look much nicer with proper CSS and potentially a front-end framework like Bootstrap.
  • User profiles: Create custom profiles for each user.

Django provides tools and documentation for all these features, making it a fantastic framework to learn for web development. Keep exploring!

Comments

Leave a Reply