TemplateDoesNotExist at /catalog/books/

67 views
Skip to first unread message

Никита Назаров

unread,
Oct 5, 2021, 4:37:19 PM10/5/21
to Django users

Hello!
I’m beginner in Django. I do Django Tutorial from Mozilla.
I get TemplateDoesNotExist at /catalog/books/ . Could you help me?. I don’t understand how to resolve it.

/catalog/urls

from django.urls import path

from . import views

urlpatterns = [

    path('', views.index, name='index'),

    path('books/', views.BookListView.as_view(), name='books'),

    path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),

]

catalog/models

# Used to generate URLs by reversing the URL patterns

from django.urls import reverse

from django.db import models

from django.urls import reverse

import uuid

# Create your models here

class Genre(models.Model):

    """Model representing a book genre (e.g. Science Fiction, Non Fiction)."""

    name = models.CharField(

        max_length=200,

        help_text="Enter a book genre (e.g. Science Fiction, French Poetry etc.)"

    )

    def __str__(self):

        """String for representing the Model object (in Admin site etc.)"""

        return self.name

class Book(models.Model):

    """Model representing a book (but not a specific copy of a book)."""

    title = models.CharField(max_length=200)

    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)

    # Foreign Key used because book can only have one author, but authors can have multiple books

    # Author as a string rather than object because it hasn't been declared yet in file.

    summary = models.TextField(

        max_length=1000, help_text="Enter a brief description of the book")

    isbn = models.CharField('ISBN', max_length=13,

                            unique=True,

                            help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn'

                                      '">ISBN number</a>')

    genre = models.ManyToManyField(

        Genre, help_text="Select a genre for this book")

    # ManyToManyField used because a genre can contain many books and a Book can cover many genres.

    # Genre class has already been defined so we can specify the object above.

    language = models.ForeignKey(

        'Language', on_delete=models.SET_NULL, null=True)

    class Meta:

        ordering = ['title', 'author']

    def display_genre(self):

        """Creates a string for the Genre. This is required to display genre in Admin."""

        return ', '.join([genre.name for genre in self.genre.all()[:3]])

    display_genre.short_description = 'Genre'

    def get_absolute_url(self):

        """Returns the url to access a particular book instance."""

        return reverse('book-detail', args=[str(self.id)])

    def __str__(self):

        """String for representing the Model object."""

        return self.title

class Language(models.Model):

    name = models.CharField(

        max_length=50, help_text="Enter the book's natural language (e.g. English, French, Japanese etc.)")

    def __str__(self):

        return self.name

class BookInstance(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4,

                          help_text="Unique ID for this particular book across whole library")

    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)

    imprint = models.CharField(max_length=200)

    due_back = models.DateField(null=True, blank=True)

    LOAN_STATUS = (

        ('m', 'Maintenance'),

        ('o', 'On loan'),

        ('a', 'Available'),

        ('r', 'Reserved'),

    )

    status = models.CharField(max_length=1, choices=LOAN_STATUS,

                              blank=True, default='m', help_text='Book availability')

    class Meta:

        ordering = ["due_back"]

    def __str__(self):

        """

        String for representing the Model object

        """

        return '%s (%s)' % (self.id, self.book.title)

class Author(models.Model):

    """

    Model representing an author.

    """

    first_name = models.CharField(max_length=100)

    last_name = models.CharField(max_length=100)

    date_of_birth = models.DateField(null=True, blank=True)

    date_of_death = models.DateField('Died', null=True, blank=True)


    def get_absolute_url(self):

        """

        Returns the url to access a particular author instance.

        """

        return reverse('author-detail', args=[str(self.id)])


    def __str__(self):

        """

        String for representing the Model object.

        """

        return '%s, %s' % (self.last_name, self.first_name)

catalog/views

from django.views import generic

from django.shortcuts import render


# Create your views here.

from .models import Book, Author, BookInstance, Genre



def index(request):

    """View function for home page of site."""


    # Generate counts of some of the main objects

    num_books = Book.objects.all().count()

    num_instances = BookInstance.objects.all().count()


    # Available books (status = 'a')

    num_instances_available = BookInstance.objects.filter(

        status__exact='a').count()


    # The 'all()' is implied by default.

    num_authors = Author.objects.count()


    context = {

        'num_books': num_books,

        'num_instances': num_instances,

        'num_instances_available': num_instances_available,

        'num_authors': num_authors,

    }


    # Render the HTML template index.html with the data in the context variable

    return render(request, 'catalog/index.html', context=context)



class BookListView(generic.ListView):

    """Generic class-based view for a list of books."""

    model = Book

    paginate_by = 10



class BookDetailView(generic.DetailView):

    """Generic class-based detail view for a book."""

    model = Book


locallibrary/settings.py

"""

Django settings for locallibrary project.


Generated by 'django-admin startproject' using Django 3.2.7.


For more information on this file, see

https://docs.djangoproject.com/en/3.2/topics/settings/


For the full list of settings and their values, see

https://docs.djangoproject.com/en/3.2/ref/settings/

"""


import os

from pathlib import Path


# Build paths inside the project like this: BASE_DIR / 'subdir'.

BASE_DIR = Path(__file__).resolve().parent.parent



# Quick-start development settings - unsuitable for production

# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/


# SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = 'django-insecure-k6nhe44hm-a90^cs6**sre$8ajn7u!e735ou4c(1iqk-ga&g!9'


# SECURITY WARNING: don't run with debug turned on in production!

DEBUG = os.environ.get('DJANGO_DEBUG', '') != 'False'


ALLOWED_HOSTS = []



# Application definition


INSTALLED_APPS = [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'catalog.apps.CatalogConfig',

]


MIDDLEWARE = [

    'django.middleware.security.SecurityMiddleware',

    'django.contrib.sessions.middleware.SessionMiddleware',

    'django.middleware.common.CommonMiddleware',

    'django.middleware.csrf.CsrfViewMiddleware',

    'django.contrib.auth.middleware.AuthenticationMiddleware',

    'django.contrib.messages.middleware.MessageMiddleware',

    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]


ROOT_URLCONF = 'locallibrary.urls'


TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [os.path.join(BASE_DIR, 'templates')],

        'APP_DIRS': True,

        'OPTIONS': {

            'context_processors': [

                'django.template.context_processors.debug',

                'django.template.context_processors.request',

                'django.contrib.auth.context_processors.auth',

                'django.contrib.messages.context_processors.messages',

            ],

        },

    },

]


WSGI_APPLICATION = 'locallibrary.wsgi.application'



# Database

# https://docs.djangoproject.com/en/3.2/ref/settings/#databases


DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': BASE_DIR / 'db.sqlite3',

    }

}



# Password validation

# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators


AUTH_PASSWORD_VALIDATORS = [

    {

        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',

    },

    {

        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',

    },

    {

        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',

    },

    {

        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',

    },

]



# Internationalization

# https://docs.djangoproject.com/en/3.2/topics/i18n/


LANGUAGE_CODE = 'en-us'


TIME_ZONE = 'Europe/London'


USE_I18N = True


USE_L10N = True


USE_TZ = True



# Static files (CSS, JavaScript, Images)

# https://docs.djangoproject.com/en/3.2/howto/static-files/


STATIC_URL = '/static/'


# Default primary key field type

# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field


DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'


Path templates
locallibrary
-----catalog
------ templates
------ base_generis.html
-------book_detail.html
----------catalog
----------book_list.html
----------index.html

book_list.html

{% extends "base_generic.html" %}


{% block content %}

    <h1>Book List</h1>


    {% if book_list %}

    <ul>


      {% for book in book_list %}

      <li>

        <a href="{{ book.get_absolute_url }}">{{ book.title }}</a> ({{book.author}})

      </li>

      {% endfor %}


    </ul>

    {% else %}

      <p>There are no books in the library.</p>

    {% endif %} 

{% endblock %}

index.html

{% extends "base_generic.html" %}


{% block title %}

<title>Стартовая страница</title>

{% endblock %}


{% block content %}

<h1>Local Library Home</h1>


<p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla

   Developer Network.</p>


<h2>Dynamic content</h2>


<p>The library has the following record counts:</p>

<ul>

   <li><strong>Books:</strong> {{ num_books }}</li>

   <li><strong>Copies:</strong> {{ num_instances }}</li>

   <li><strong>Copies available:</strong> {{ num_instances_available }}</li>

   <li><strong>Authors:</strong> {{ num_authors }}</li>

</ul>


{% endblock %}

traceback message

Environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/catalog/books/

Django Version: 3.2.7
Python Version: 3.9.7
Installed Applications:
[‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘catalog.apps.CatalogConfig’]
Installed Middleware:
[‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’]

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

Using engine django:
* django.template.loaders.filesystem.Loader: /Users/nikita/Documents/Github/devsearch/hello-world/locallibrary/templates/catalog/book_list.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/contrib/admin/templates/catalog/book_list.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/contrib/auth/templates/catalog/book_list.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /Users/nikita/Documents/Github/devsearch/hello-world/locallibrary/catalog/templates/catalog/book_list.html (Source does not exist)

Traceback (most recent call last):
File “/Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/core/handlers/exception.py”, line 47, in inner
response = get_response(request)
File “/Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/core/handlers/base.py”, line 204, in _get_response
response = response.render()
File “/Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/template/response.py”, line 105, in render
self.content = self.rendered_content
File “/Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/template/response.py”, line 81, in rendered_content
template = self.resolve_template(self.template_name)
File “/Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/template/response.py”, line 63, in resolve_template
return select_template(template, using=self.using)
File “/Users/nikita/Documents/Github/devsearch/hello-world/myproject_env/lib/python3.9/site-packages/django/template/loader.py”, line 47, in select_template
raise TemplateDoesNotExist(’, '.join(template_name_list), chain=chain)

Exception Type: TemplateDoesNotExist at /catalog/books/
Exception Value: catalog/book_list.html

Adeyemi Deji

unread,
Oct 6, 2021, 4:20:19 AM10/6/21
to Django users
Hi, I observed that you didn't specify the template name attribute for the BookListView and BookDetailView, that should solve you problem.

Никита Назаров

unread,
Oct 6, 2021, 5:31:34 AM10/6/21
to Django users
Hello!
Thank you!
I'm sorry. How could I do this? 

среда, 6 октября 2021 г. в 11:20:19 UTC+3, adeyem...@gmail.com:

Adeyemi Deji

unread,
Oct 6, 2021, 5:44:56 AM10/6/21
to django...@googlegroups.com
for example.
class AboutView(TemplateView):
    template_name = "about.html"

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/17c51485-19f7-4693-aa4d-1e69e9a7ddd8n%40googlegroups.com.

Никита Назаров

unread,
Oct 6, 2021, 7:10:06 AM10/6/21
to django...@googlegroups.com
It doesn't seem to work. I wrote your example in views.py. 
Or I might make mistakes. Could you see? 

views. py
from .models import Book, Author, BookInstance, Genre
from django.views import generic
from django.shortcuts import render
from django.views.generic.base import TemplateView

# Create your views here.


def index(request):
"""View function for home page of site."""

# Generate counts of some of the main objects
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()

# Available books (status = 'a')
num_instances_available = BookInstance.objects.filter(
status__exact='a').count()

# The 'all()' is implied by default.
num_authors = Author.objects.count()

context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
}

# Render the HTML template index.html with the data in the context variable
return render(request, 'catalog/index.html', context=context)


class BookListView(TemplateView):
template_name = "catalog/book_list.html"


class BookDetailView(TemplateView):
template_name = "catalog/book_detail.html"


urls.py
from django.urls import path
from . import views


urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='books'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
]




ср, 6 окт. 2021 г. в 12:45, Adeyemi Deji <adeyem...@gmail.com>:
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/8R6KRoYcHM0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAEO1GrrcCMRPuhkE_4xN8WJkRdf7LTYCbFNxSP4jfwK3Gq2QWQ%40mail.gmail.com.

Adeyemi Deji

unread,
Oct 6, 2021, 7:22:22 AM10/6/21
to django...@googlegroups.com
Please don't change your formal code setting, just add the template_name attribute and specify the template you are referring to
just add this to your former code:
template_name = "catalog/book_list.html"

Virus-free. www.avast.com


Virus-free. www.avast.com

Adeyemi Deji

unread,
Oct 6, 2021, 7:24:15 AM10/6/21
to django...@googlegroups.com

class BookListView(generic.ListView):

    """Generic class-based view for a list of books."""

    model = Book

    paginate_by = 10

    template_name = "catalog/book_list.html"


Virus-free. www.avast.com

Никита Назаров

unread,
Oct 6, 2021, 9:09:33 AM10/6/21
to django...@googlegroups.com
It also doesn't work. I see this error :"TemplateDoesNotExist at /catalog/books/ catalog/book_list.html, catalog/book_list.html"
My views.py is below.
Also, I checked on GitHub Mozilla (https://github.com/mdn/django-locallibrary-tutorial/blob/master/catalog/views.py). They didn't use - template_name.
I'm completely confused. 

from .models import Book, Author, BookInstance, Genre
from django.views import generic
from django.shortcuts import render
from django.views.generic.base import TemplateView

# Create your views here.


def index(request):
"""View function for home page of site."""

# Generate counts of some of the main objects
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()

# Available books (status = 'a')
num_instances_available = BookInstance.objects.filter(
status__exact='a').count()

# The 'all()' is implied by default.
num_authors = Author.objects.count()

context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
}

# Render the HTML template index.html with the data in the context variable
return render(request, 'index.html', context=context)


class BookListView(generic.ListView):

"""Generic class-based view for a list of books."""

model = Book
paginate_by = 10
template_name = "catalog/book_list.html"


class BookDetailView(generic.DetailView):

"""Generic class-based detail view for a book."""
model = Book
template_name = "catalog/book_detail.html"



ср, 6 окт. 2021 г. в 14:24, Adeyemi Deji <adeyem...@gmail.com>:

Adeyemi Deji

unread,
Oct 6, 2021, 9:19:03 AM10/6/21
to django...@googlegroups.com
Please correct your class views, you are getting it wrong.
it should look like this.

class BookListView(generic.ListView):
        model = Book
        paginated_by = 10
        template_name = "catalog/book_list.html"

class BookDetailView(generic.DetailView):
        model = Book
        template_name = "catalog/book_detail.html"

Virus-free. www.avast.com

Adeyemi Deji

unread,
Oct 6, 2021, 9:19:43 AM10/6/21
to django...@googlegroups.com
correct paginated_by to paginate_by.

Virus-free. www.avast.com

Никита Назаров

unread,
Oct 6, 2021, 11:00:42 AM10/6/21
to django...@googlegroups.com
Thank you!
I corrected as you wrote. But I also have this mistake (
TemplateDoesNotExist at /catalog/books/
catalog/book_list.html, catalog/book_list.html).
Might I take the wrong path? (my path is below picture)
Also thank you for helping me. I am grateful to you. I have had this problem for 1 week. 
image.png


ср, 6 окт. 2021 г. в 16:19, Adeyemi Deji <adeyem...@gmail.com>:

Adeyemi Deji

unread,
Oct 6, 2021, 11:16:34 AM10/6/21
to Django users
Okay, I also noticed something in the TEMPLATES VARIABLE in your settings.py file, please make DIRS an empty list like this [] with no space or better still change to [os.path.join(BASE_DIR, 'catalog/templates')]

Никита Назаров

unread,
Oct 6, 2021, 11:26:19 AM10/6/21
to django...@googlegroups.com
No, both variants don't work. 

ср, 6 окт. 2021 г. в 18:17, Adeyemi Deji <adeyem...@gmail.com>:

Adeyemi Deji

unread,
Oct 6, 2021, 12:40:37 PM10/6/21
to Django users
Hi, please make reference to link below, looks similar to what you are building

Also I will read up the documentation to find solution to this issue. You can take a break, you have really worked hard today. 

Никита Назаров

unread,
Oct 6, 2021, 1:16:38 PM10/6/21
to django...@googlegroups.com
Thank you so much! 

ср, 6 окт. 2021 г. в 19:41, Adeyemi Deji <adeyem...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages