Search code examples
djangodjango-templatesdjango-settingscookiecutter-django

Cookiecutter Django - ListView expects templates in different directory to Views?


Cookiecutter generates the app users automatically under my_project directory. I've placed my_app in the same directory / listed it under INSTALLED_APPS and it works fine. I then created my templates folder under my_project/templates/my_app/ (same as the generated users templates).

When using a View, I received a TemplateDoesNotExistError. So Instead, I put templates under my_project/my_app/templates in which case it worked. When I used ListView, I recieved the same error. So I moved this template to the previous folder, and it works.

- requirements
- my_project
    - contrib
    ▒   - sites
    ▒       - migrations
    - static
    ▒   - css
    ▒   - fonts
    ▒   - images
    ▒   ▒   - favicons
    ▒   - js
    - templates
    ▒   - account
    ▒   - pages
    ▒   - my_app
    ▒           - item_list.html <- only works here (ListView)
    ▒   - users
    - my_app
    ▒   - migrations
    ▒   - templates
    ▒           - item_detail.html <- only works here (View)
    - users
    ▒   - migrations
    ▒   - tests
    - utils

What am I missing here? I would like to keep my templates together in one folder obviously. If I switch the templates/directories around, I get TemplateDoesNotExistError.

These are my relevant (I think?) settings.

settings/base.py

ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent
APPS_DIR = ROOT_DIR / "my_project"

INSTALLED_APPS = [
    ...
    "my_project.users",
    "my_project.my_app",
    ...
]

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [str(APPS_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.template.context_processors.i18n",
                "django.template.context_processors.media",
                "django.template.context_processors.static",
                "django.template.context_processors.tz",
                "django.contrib.messages.context_processors.messages",
                "my_project.users.context_processors.allauth_settings",
            ],
        },
    }
]

my_project/my_app/apps.py

from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _


class MyAppConfig(AppConfig):
    # default_auto_field = "django.db.models.BigAutoField"
    name = "my_project.my_app"
    verbose_name = _("My_App") # not really this but you get it

    def ready(self):
        try:
            import my_project.my_app.signals  # noqa F401
        except ImportError:
            pass

According to this answer, maybe I've misconfigured the INSTALLED_APP?

  1. add <project_slug>.<name-of-the-app>.apps.<NameOfTheAppConfigClass>, on your LOCAL_APPS on config/settings/base.py

EDIT: my_project.my_app.apps.MyAppConfig added to LOCAL_APPS and doesn't make a difference...


Solution

  • 12 hours later I re-did the entire cookiecutter django process following a well written guide, then copied over my models, views, urls, templates - and the issue was still there...

    Thankfully the guide shows many view examples (unlike the docs!) and I noticed my view:

    class ItemView(LoginRequiredMixin, View):
        """ Item Detail """
    
        template_name = "item.html"
    

    should have been:

    class ItemView(LoginRequiredMixin, View):
        """ Item Detail """
    
        template_name = "my_app/item.html"
    

    Now everything lives happily under the same template folder.