How can I resolve this Django TemplateDoesNotExist error?

I'm working through the "Django 5 by Example" textbook, and am nearly finished with chapter 12, however at the very end when the text asks you to runserver and checkout http://127.0.0.1:8000/accounts/login, I get the following error:

TemplateDoesNotExist at /accounts/login/ registration/login.html Request Method: GET Request URL: http://127.0.0.1:8000/accounts/login/ Django Version: 5.2.5 Exception Type: TemplateDoesNotExist Exception Value: registration/login.html Exception Location: C:\Users\Zergy\python\django\django-learning\env\educa\Lib\site-packages\django\template\loader.py, line 47, in select_template Raised during: django.contrib.auth.views.LoginView Python Executable: C:\Users\Zergy\python\django\django-learning\env\educa\Scripts\python.exe Python Version: 3.13.1 Python Path: ['C:\Users\Zergy\python\django\django-learning\educa', 'C:\Users\Zergy\AppData\Local\Programs\Python\Python313\python313.zip', 'C:\Users\Zergy\AppData\Local\Programs\Python\Python313\DLLs', 'C:\Users\Zergy\AppData\Local\Programs\Python\Python313\Lib', 'C:\Users\Zergy\AppData\Local\Programs\Python\Python313', 'C:\Users\Zergy\python\django\django-learning\env\educa', 'C:\Users\Zergy\python\django\django-learning\env\educa\Lib\site-packages']

Template-loader postmortem Django tried loading these templates, in this order:

Using engine django:

django.template.loaders.app_directories.Loader: C:\Users\Zergy\python\django\django-learning\env\educa\Lib\site-packages\django\contrib\admin\templates\registration\login.html (Source does not exist) django.template.loaders.app_directories.Loader: C:\Users\Zergy\python\django\django-learning\env\educa\Lib\site-packages\django\contrib\auth\templates\registration\login.html (Source does not exist)

I have checked, double-checked and triple-checked that my spelling and file structure are the same as what is given in the textbook, but the error persists.
Here's the relevant parts of settings.py:

INSTALLED_APPS = [
    'courses.apps.CoursesConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

ROOT_URLCONF = 'educa.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Here is the file structure

file structure

Here is educa/urls.py

from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('accounts/login/', auth_views.LoginView.as_view(), name='login'),
    path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'),
    path('admin/', admin.site.urls),
]

if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
    )

Here is courses/templates/base.html

{% load static %}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>{% block title %}Educa{% endblock title %}</title>
        <link rel="stylesheet" href="{% static "css/base.css" %}">
    </head>
    <body>
        <div id="header">
            <a href="/" class="logo">Educa</a>
            <ul class="menu">
                {% if request.user.is_authenticated %}
                    <li>
                        <form action="{% url "logout" %}" method="post">
                            <button type="submit">Sign out</button>
                        </form>
                    </li>
                {% else %}
                    <li><a href="{% url "login" %}">Sign in</a></li>
                {% endif %}
            </ul>
        </div>
        <div id="content">
            {% block content %}
            {% endblock content %}
        </div>
        <script>
            document.addEventListener('DOMContentLoaded', (event) => {
                // DOM DOMContentLoaded
                {% block domready %}
                {% endblock %}
            })
        </script>
    </body>
</html>

here is courses/templates/registration/login.html

{% extends "base.html" %}

{% block title %}Log-in{% endblock title %}

{% block content %}
    <h1>Log-in</h1>
    <div class="module">
        {% 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 action="{% url 'login' %}" method="post">
                {{ form.as_p }}
                {% csrf_token %}
                <input type="hidden" name="next" value="{{ next }}" />
                <p><input type="submit" value="Log-in"></p>
            </form>
        </div>
    </div>
{% endblock content %}

finally here is courses/admin.py (if needed)

from django.contrib import admin
from .models import Subject, Course, Module

@admin.register(Subject)
class SubjectAdmin(admin.ModelAdmin):
    list_display = ['title', 'slug']
    prepopulated_fields = {'slug': ('title',)}

class ModuleInline(admin.StackedInline):
    model = Module

@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    list_display = ['title', 'subject', 'created']
    list_filter = ['created', 'subject']
    search_fields = ['title', 'overview']
    prepopulated_fields = {'slug': ('title',)}
    inlines = [ModuleInline]

I have checked a number of old stackoverflow posts regarding this error, but none of the solutions I have seen (such as adding a / at the end of the url route) were relevant to my situation. I have done all I can apart from literally copy pasting the entire repository here to make my project look like the textbook, but I still get this error. My intuition tells me that the folder structure is somehow wrong, but if so, why does the textbook show it like this? Is it outdated?

TEMPLATES = [{
  "BACKEND": "django.template.backends.django.DjangoTemplates",
  "DIRS": [],
  "APP_DIRS": True,   # <-- must be True
  "OPTIONS": {"context_processors": [
    "django.template.context_processors.request",
    "django.contrib.auth.context_processors.auth",
    "django.contrib.messages.context_processors.messages",
  ]},
}]
courses/templates/registration/login.html
path("accounts/login/",
     auth_views.LoginView.as_view(template_name="registration/login.html"),
     name="login")
Вернуться на верх