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>© 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.
-
Navigate to the
blog
app’stemplates
directory and create aregistration
folder:- Inside the
blog
app folder, create atemplates
folder (if it doesn’t already exist), and then create aregistration
subfolder inside it.
Your structure should look like this:
myblog/ blog/ templates/ registration/ login.html
- Inside the
-
Add the following code to
login.html
to extend thebase.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.
Step 7: Add a Logout Link (Every Exit Needs a Grand Doorway)
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
- Lesson 6: User Profiles – Because Everyone Deserves a Little Spotlight
- Lesson 5: User Registration – Because Only the Worthy Should Comment!
- Lesson 3: Forms – The Art of Asking Nicely for User Input (Without Scaring Them Away)
- Lesson 2: The Model-View-Template (MVT) Pattern – Like MVC, But With More Magic and Less Headaches
- Django: The Web Framework That'll Make You Feel Like a Code Wizard (Without the Spellbook)