Lesson 4: User Authentication – Because Not Everyone Should Have Access to Your Blog's Inner Sanctum


Lesson 4

Lesson 4: User Authentication – Because Not Everyone Should Have Access to Your Blog’s Inner Sanctum

Hello again, code wizards! 🧙‍♂️ By now, you’ve built a blog, enabled comments, and maybe even gotten feedback like “Nice font choice” (or “Why Comic Sans?”). But today, we’re taking things up a notch—because not everyone should have VIP access to your blog’s inner sanctum.

Today, we’re going to sprinkle some login and logout magic. And to make everything look polished, we’ll introduce a base template (base.html) to structure your pages uniformly. Plus, we’ll ensure a logout redirect, so users don’t end up in limbo after they exit the VIP area.

Let’s dive in!


Step 1: Activate the Virtual Environment (A.K.A., Put on Your Wizard Robes)

Before we cast any spells, make sure your virtual environment is active. This is like making sure you’ve got your wizard’s robe on before casting a fireball. We don’t want any spell mishaps, right?

Check if it’s active by running:

echo $VIRTUAL_ENV

If you get a path as a response, great! You’re all set. If not, time to activate it:

source venv/bin/activate

Once you see (venv) at the beginning of your terminal prompt, you know you’re in your cozy little coding bubble where all your dependencies are safe and sound. Like a magic barrier that keeps the goblins out. 🛡️


Step 2: Built-in User Authentication (Django – Your Coding Butler)

Guess what? Django’s got your back—it has a built-in user authentication system, meaning you don’t need to build login functionality from scratch (because who has time for that?). Django’s like a coding butler, silently handling all the heavy lifting so you can focus on more important things—like deciding which snack to eat while coding.

Let’s set it up!

Navigate to myblog/myblog/urls.py (yes, that’s two “myblog” folders) and add these lines to include the login and logout views:

from django.contrib.auth import views as auth_views
from django.urls import path, include  # Import include to reference app URLs

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),  # Include the blog app's URLs
    path('login/', auth_views.LoginView.as_view(), name='login'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

Now Django’s taking care of login and logout. Fancy, right? It’s like hiring an invisible butler for your code.


Step 3: Redirect After Login and Logout (Because Nobody Wants to End Up in Limbo)

By default, Django redirects users to /accounts/profile/ after login, but let’s be real—nobody wants to land on some random, boring page. Let’s also handle where they go after logging out, so they get a friendly exit.

Add Login Redirect:

Open your settings.py file (located in myblog/myblog/settings.py) and add this magic line:

# Redirect to the blog homepage after login
LOGIN_REDIRECT_URL = '/blog/'

Add Logout Redirect:

To ensure a smooth exit, add this line in the same settings.py file:

# Redirect to the blog homepage after logout
LOGOUT_REDIRECT_URL = '/blog/'

With this spell, anyone who logs in or out gets teleported directly to your blog’s homepage, where all the cool stuff happens. 🎨


Step 4: Create the base.html Template (Your Blog’s Stylish Castle)

Let’s get serious about making your blog look consistent—because even wizards need style. We’ll create a base.html template to serve as the foundation for your blog’s structure. It’ll be like a magical castle with rooms you can decorate differently on each page. 🏰

Navigate to the blog app’s templates directory and create a base.html file:

myblog/
    blog/
        templates/
            base.html

Now, fill base.html with this beautiful layout:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}My Blog{% endblock %}</title>
</head>
<body>
    <header>
        <h1>My Blog</h1>
        <nav>
            <ul>
                <li><a href="{% url 'blog_index' %}">Home</a></li>
                <li>
                    {% if user.is_authenticated %}
                        <a href="{% url 'logout' %}">Logout</a>
                    {% else %}
                        <a href="{% url 'login' %}">Login</a>
                    {% endif %}
                </li>
            </ul>
        </nav>
    </header>

    <div class="content">
        {% block content %}
        <!-- Content specific to each page will go here -->
        {% endblock %}
    </div>

    <footer>
        <p>&copy; 2024 My Blog. All rights reserved. Also, cookies.</p>
    </footer>
</body>
</html>

We’ve now built the castle! 🎉 It’s got a header, navigation, and a footer, ready to welcome visitors. The magic happens in the {% block content %}—that’s where each page will add its own unique flavor. 🍨


Step 5: Create the login.html Template (Let’s Open the Gate)

We need to create a login page where users can log in. Django expects a login.html template to be located inside a registration folder.

  1. Navigate to the blog app’s templates directory and create a registration folder:

    • Inside the blog app folder, create a templates folder (if it doesn’t already exist), and then create a registration subfolder inside it.

    Your structure should look like this:

    myblog/
        blog/
            templates/
                registration/
                    login.html
    
  2. Add the following code to login.html to extend the base.html template:

{% extends "base.html" %}

{% block title %}Login{% endblock %}

{% block content %}
<h2>Login to Your Account</h2>
<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Login</button>
</form>
{% endblock %}

Now, your login page is ready, and it inherits the layout from base.html so it matches the rest of your site. You’re all set to let users in—but only the worthy ones! 😉


Step 6: Update blog_index.html and blog_post_detail.html

Now that we have the base.html template, let’s update the blog_index.html and blog_post_detail.html to use the same layout.

6.1 Update blog_index.html

Navigate to myblog/blog/templates/blog_index.html and update it like this:

{% extends "base.html" %}

{% block title %}Blog Home{% endblock %}

{% block content %}
<h2>Welcome to My Blog!</h2>
<ul>
    {% for post in posts %}
        <li>
            <strong><a href="{% url 'blog_post_detail' post.pk %}">{{ post.title }}</a></strong> - {{ post.created_at }}
            <p>{{ post.content|truncatewords:30 }}</p>
            <a href="{% url 'blog_post_detail' post.pk %}">Read More</a>
        </li>
    {% endfor %}
</ul>
{% endblock %}

This will extend the base.html template and give your blog index a clean, consistent layout.

6.2 Update blog_post_detail.html

Next, update myblog/blog/templates/blog_post_detail.html:

{% extends "base.html" %}

{% block title %}{{ post.title }}{% endblock %}

{% block content %}
<h2>{{ post.title }}</h2>
<p>{{ post.created_at }}</p>
<p>{{ post.content }}</p>

<h3>Comments</h3>
<ul>
    {% for comment in comments %}
        <li><strong>{{ comment.author }}</strong>: {{ comment.content }}</li>
    {% empty %}
        <li>No comments yet. Be the first to comment!</li>
    {% endfor %}
</ul>

<h3>Leave a Comment</h3>
<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Submit</button>
</form>
{% endblock %}

This will ensure the individual blog post pages also use the same layout.


What’s the fun of logging in if you can’t log out? In base.html, we’ve already added the logout link in the navigation bar. It’ll change dynamically based on whether the user is logged in or not:

{% if user.is_authenticated %}
    <a href="{% url 'logout' %}">Logout</a>
{% else %}
    <a href="{% url 'login' %}">Login</a>
{% endif %}

It’s like a magical doorway—when you log out, it quietly sends you on your way (probably to grab some coffee).


Step 8: Test the Magic (This Is Where It Gets Fun)

Time to test the login and logout functionality!

Fire up the server:

python3 manage.py runserver

Visit http://127.0.0.1:8000/login/ and try logging in. After logging in, you should be magically redirected to http://localhost:8000/blog/ (or wherever you set the LOGIN_REDIRECT_URL).

Test logging out—after which you’ll be redirected back to http://localhost:8000/blog/ (thanks to the LOGOUT_REDIRECT_URL).


Step 9: Create a Superuser (Every Castle Needs a King)

Before you finish for the day, don’t forget to create your superuser account. This gives you the keys to the kingdom!

Run this command:

python3 manage.py createsuperuser

Fill in the prompts, and boom—you’ve now got admin access to the blog.


Step 10: Deactivate the Virtual Environment (Even Wizards Need Rest)

When you’re done for the day (or need a snack), don’t forget to deactivate your virtual environment:

deactivate

You can now safely go grab that snack, knowing your Django blog is secure and stylish.


Conclusion of Lesson 4

And there you have it! 🎉 You’ve not only added user authentication (login and logout), but you’ve also designed your blog’s layout with a sleek base.html template. Plus, users will now be redirected to your homepage after logging in and logging out—because you don’t leave anyone wandering around in limbo.

Next time, we’ll look into user registration, so your blog can start gaining followers (who will definitely want to comment on your brilliant posts). Until then, kick back, admire your wizardry, and maybe reward yourself with something sweet. 🍩


See also