Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

My local machine is running Python 2.5 and Nginx on Ubuntu 8.10, with Django builded from latest development trunk.

For every URL I request, it throws:

TemplateDoesNotExist at /appname/path appname/template_name.html

Django tried loading these templates, in this order: * Using loader django.template.loaders.filesystem.function: * Using loader django.template.loaders.app_directories.function:

TEMPLATE_DIRS ('/usr/lib/python2.5/site-packages/projectname/templates',)

Is it looking for /usr/lib/python2.5/site-packages/projectname/templates/appname/template_name.html in this case? The weird thing is this file does existed on disk. Why can't Django locate it?

I run the same application on a remote server with Python 2.6 on Ubuntu 9.04 without such problem. Other settings are the same.

Is there anything misconfigured on my local machine, or what could possibly have caused such errors that I should look into?

In my settings.py , I have specified:

SETTINGS_PATH = os.path.normpath(os.path.dirname(__file__))
# Find templates in the same folder as settings.py.
TEMPLATE_DIRS = (
    os.path.join(SETTINGS_PATH, 'templates'),

It should be looking for the following files:

  • /usr/lib/python2.5/site-packages/projectname/templates/appname1/template1.html
  • /usr/lib/python2.5/site-packages/projectname/templates/appname1/template2.html
  • /usr/lib/python2.5/site-packages/projectname/templates/appname2/template3.html
  • All the above files exist on disk.

    Solved

    It works now after I tried:

    chown -R www-data:www-data /usr/lib/python2.5/site-packages/projectname/*
    

    It's strange. I don't need to do this on the remote server to make it work.

    @Jordan, TEMPLATE_DIRS accessable by root is enough. It's what it's configured on remote server which is working. – jack Dec 18, 2009 at 3:46

    mean that Django will look at the templates from templates/ directory under your project.

    Assuming your Django project is located at /usr/lib/python2.5/site-packages/projectname/ then with your settings django will look for the templates under /usr/lib/python2.5/site-packages/projectname/templates/

    So in that case we want to move our templates to be structured like this:

    /usr/lib/python2.5/site-packages/projectname/templates/template1.html
    /usr/lib/python2.5/site-packages/projectname/templates/template2.html
    /usr/lib/python2.5/site-packages/projectname/templates/template3.html
    

    Second solution:

    If that still doesn't work and assuming that you have the apps configured in settings.py like this:

    INSTALLED_APPS = (
        'appname1',
        'appname2',
        'appname3',
    

    By default Django will load the templates under templates/ directory under every installed apps. So with your directory structure, we want to move our templates to be like this:

    /usr/lib/python2.5/site-packages/projectname/appname1/templates/template1.html
    /usr/lib/python2.5/site-packages/projectname/appname2/templates/template2.html
    /usr/lib/python2.5/site-packages/projectname/appname3/templates/template3.html
    

    SETTINGS_PATH may not be defined by default. In which case, you will want to define it (in settings.py):

    import os
    SETTINGS_PATH = os.path.dirname(os.path.dirname(__file__))
                    @jpartogi, I tried both approaches but neither works. I even tried to use absolute path to template in render_to_response() argument but still didn't work.
    – jack
                    Dec 18, 2009 at 4:56
                    To put every template from different apps in one directory templates is not  a good design. But, as I know, after adding your APP_NAME in the settings.py, django might go to search the app's template under the directory which is under the APP_DIR. Thus, you can separate the template for various app. (Django 1.7 - .1.9
    – Alston
                    Jul 2, 2016 at 14:52
                    Django TEMPLATE_DIRSis deprecated since 1.8, docs.djangoproject.com/en/1.8/ref/settings/#template-dirs
    – Emily
                    Sep 21, 2018 at 2:57
                'BACKEND': 'django.template.backends.django.DjangoTemplates',
                'DIRS': [],
                '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',
    

    You need to add to 'DIRS' the string

    os.path.join(BASE_DIR, 'templates')
    

    So altogether you need:

    TEMPLATES = [
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(SETTINGS_PATH, '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',
                    SETTINGS_PATH is not actually defined anywhere, so I do not think that this answer will work. Maybe you meant BASE_DIR
    – sofly
                    Feb 3, 2016 at 21:05
                    I think Shapon Pal means SETTINGS_PATH = os.path.dirname(os.path.dirname(__file__)), not file
    – mic
                    Aug 14, 2019 at 23:40
                    Thanks this worked for me. there are lots of little pieces to orchestrate when setting up django, so this might work for some people but no others. Lots of good solutions in other responses on this post, too!
    – Mohammad Athar
                    Aug 15, 2021 at 16:42
    

    If you encounter this problem when you add an app from scratch. It is probably because that you miss some settings. Three steps is needed when adding an app.

    1、Create the directory and template file.

    Suppose you have a project named mysite and you want to add an app named your_app_name. Put your template file under mysite/your_app_name/templates/your_app_name as following.

    ├── mysite
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── your_app_name
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── templates
    │   │   └── your_app_name
    │   │       └── my_index.html
    │   ├── urls.py
    │   └── views.py
    

    2、Add your app to INSTALLED_APPS.

    Modify settings.py

    INSTALLED_APPS = [
        'your_app_name',
    

    3、Add your app directory to DIRS in TEMPLATES.

    Modify settings.py.

    Add os import

    import os
    TEMPLATES = [
            'DIRS': [os.path.join(BASE_DIR, 'templates'),
                     os.path.join(BASE_DIR, 'your_app_name', 'templates', 'your_app_name'),
                    In my case only step 2 was missing. the DIRS array I could leave that empty and it still worked and looked for the template in the right templates directory of the app.
    – Shri Shinde
                    Apr 30, 2020 at 11:05
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['/home/jay/apijay/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',
    

    As of Django version tested on version 3, You need to add your new app to installed app. No other code change is required for a django app

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'addyourappnamehere'
    

    Django TemplateDoesNotExist error means simply that the framework can't find the template file.

    To use the template-loading API, you'll need to tell the framework where you store your templates. The place to do this is in your settings file (settings.py) by TEMPLATE_DIRS setting. By default it's an empty tuple, so this setting tells Django's template-loading mechanism where to look for templates.

    Pick a directory where you'd like to store your templates and add it to TEMPLATE_DIRS e.g.:

    TEMPLATE_DIRS = (
      '/home/django/myproject/templates',
    

    May, 2023 Update:

    templates folder can be put just under django-project folder or just under each app folder as shown below:

    django-project
     |-core
     │  |-settings.py
     │  └-urls.py
     |-app1
     |  |-urls.py
     |  └-views.py
     |-app2
     |  |-urls.py
     |  └-views.py
     └-templates # Here
        |-app1
        |  └-a1.html
        └-app2
           └-a2.html
    
    django-project
     |-core
     │  |-settings.py
     │  └-urls.py
     |-app1
     |  |-urls.py
     |  |-views.py
     |  └-templates # Here
     |     └-app1
     |        └-a1.html
     └-app2
        |-urls.py
        |-views.py
        └-templates # Here
           └-app2
              └-a2.html
    

    For example first, you need set "app1" and "app2" to INSTALLED_APPS in settings.py as shown below:

    # "core/settings.py"
    INSTALLED_APPS = [
        "app1",
        "app2",
    

    Then if templates folder is just under django-project folder as shown below:

    django-project
     |-core
     │  |-settings.py
     │  └-urls.py
     |-app1
     |  |-urls.py
     |  └-views.py
     |-app2
     |  |-urls.py
     |  └-views.py
     └-templates # Here
        |-app1
        |  └-a1.html
        └-app2
           └-a2.html
    

    Then, you need to set BASE_DIR / 'templates' to "DIRS" in TEMPLATES in settings.py as shown below. *I recommend to put templates folder just under django-project folder as shown above because you can easily manage templates in one place:

    # "core/settings.py"
    TEMPLATES = [
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            "DIRS": [
                BASE_DIR / 'templates' # Here
            "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",
    

    And, if templates folder is just under each app folder as shown below:

    django-project
     |-core
     │  |-settings.py
     │  └-urls.py
     |-app1
     |  |-urls.py
     |  |-views.py
     |  └-templates # Here
     |     └-app1
     |        └-a1.html
     └-app2
        |-urls.py
        |-views.py
        └-templates # Here
           └-app2
              └-a2.html
    

    Then, you need to keep "DIRS" empty (which is default) without setting BASE_DIR / 'templates' to "DIRS" in TEMPLATES in settings.py as shown below:

    # "core/settings.py"
    TEMPLATES = [
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            "DIRS": [], # Keep it empty
            "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",
    

    Then, define test() in app1/views.py and app2/views.py as shown below. Be careful, you need to set "app1/a1.html" and "app2/a2.html" instead of just setting "a1.html" and "a2.html" in render() as shown below:

    # "app1/views.py"
    from django.shortcuts import render
    def test(request):         # Don't set just "a1.html"
        return render(request, "app1/a1.html")
    
    # "app2/views.py"
    from django.shortcuts import render
    def test(request):         # Don't set just "a2.html"
        return render(request, "app2/a2.html")
    

    Then, set each test view of app1 and app2 in app1/urls.py and app2/urls.py as shown below:

    # "app1/urls.py"
    from django.urls import include, path
    from . import views
    app_name = "app1"
    urlpatterns = [
        path("", views.test, name='test'), # Here
    
    # "app2/urls.py"
    from django.urls import include, path
    from . import views
    app_name = "app2"
    urlpatterns = [
        path("", views.test, name='test'), # Here
    

    Then, set each urls.py of app1 and app2 in core/urls.py as shown below, then the templates of app1 and app2 will be rendered without any errors:

    # "core/urls.py"
    from django.urls import include, path
    urlpatterns = [
        path("app1/", include('app1.urls')), # Here
        path("app2/", include('app2.urls'))  # Here
    

    Lastly again, I recommend to put templates folder just under django-project folder as shown below because you can easily manage templates in one place:

    django-project
     |-core
     │  |-settings.py
     │  └-urls.py
     |-app1
     |  |-urls.py
     |  └-views.py
     |-app2
     |  |-urls.py
     |  └-views.py
     └-templates # Here
        |-app1
        |  └-a1.html
        └-app2
           └-a2.html
                    This worked for me.   Loads templates from Django apps on the filesystem. For each app in INSTALLED_APPS, the loader looks for a templates subdirectory. If the directory exists, Django looks for templates in there.  <br> TEMPLATES = [{     'BACKEND': 'django.template.backends.django.DjangoTemplates',     'APP_DIRS': True, }]
    – Vijay
                    Jun 6, 2015 at 13:50
    

    It works now after I tried

    chown -R www-data:www-data /usr/lib/python2.5/site-packages/projectname/*
    

    It's strange. I dont need to do this on the remote server to make it work.

    Also, I have to run the following command on local machine to make all static files accessable but on remote server they are all "root:root".

    chown -R www-data:www-data /var/www/projectname/*
    

    Local machine runs on Ubuntu 8.04 desktop edition. Remote server is on Ubuntu 9.04 server edition.

    Anybody knows why?

    Make sure you've added your app to the project-name/app-namme/settings.py INSTALLED_APPS: .

    INSTALLED_APPS = ['app-name.apps.AppNameConfig']
    

    And on project-name/app-namme/settings.py TEMPLATES: .

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

    add rest_framework to the INSTALLED_APPS if django rest framework. For my case I had missed adding it to the installed apps.

    INSTALLED_APPS = [
        '..........',,
        'rest_framework',
        '.........',
    

    See which folder django try to load template look at Template-loader postmortem in error page, for example, error will sothing like this:

    Template-loader postmortem
    Django tried loading these templates, in this order:
    Using engine django:
    django.template.loaders.filesystem.Loader: d:\projects\vcsrc\vcsrc\templates\base.html (Source does not exist)
    

    In my error vcsrc\vcsrc\templates\base.html not in path.
    Then change TEMPLATES in setting.py file to your templates path

    TEMPLATES = [
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
             # 'DIRS': [], 
            'DIRS': [os.path.join(BASE_DIR, 'vcsrc/templates')], 
    

    In my case it was enough just to include my application in INSTALLED_APPS in the settings.py file:

    INSTALLED_APPS = [
        "myapp",
        "django.contrib.admin",
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",
        "django.contrib.messages",
        "django.contrib.staticfiles",
    

    Also, remember that the template should be placed in your directory like so: myapp/templates/myapp/template_name.html but when you point at this template you do this like that: template = loader.get_template("myapp/template_name.html")

    django was configured to use templates in project_name/app_name/templates/app_name/template.html when referred with render(request, 'app_name/template.html', context)

    If you got Template exception the reason is that you hadn't add app_name to installed_apps in settings.

    I had the issue with django 4.1

    and it still showed the error, then I realized that in another project the templates was showing without adding that code in settings.py file so I checked that project and I realized that I didn't create a virtual environment in this project so I did

    virtualenv env 
    

    and it worked, don't know why

    I came up with this problem. Here is how I solved this:

    Look at your settings.py, locate to TEMPLATES variable, inside the TEMPLATES, add your templates path inside the DIRS list. For me, first I set my templates path as TEMPLATES_PATH = os.path.join(BASE_DIR,'templates'), then add TEMPLATES_PATH into DIRS list, 'DIRS':[TEMPLATES_PATH,]. Then restart the server, the TemplateDoesNotExist exception is gone. That's it.

    1.create a folder 'templates' in your 'app'(let say you named such your app) and you can put the html file here. But it s strongly recommended to create a folder with same name('app') in 'templates' folder and only then put htmls there. Into the 'app/templates/app' folder

    2.now in 'app' 's urls.py put:

      path('', views.index, name='index'), # in case of  use default server index.html 
    

    3. in 'app' 's views.py put:

    from django.shortcuts import render 
    def index(request): return
        render(request,"app/index.html")
        # name 'index' as you want
    

    Works on Django 3

    I found I believe good way, I have the base.html in root folder, and all other html files in App folders, I settings.py

    import os
    # This settings are to allow store templates,static and media files in root folder
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    TEMPLATE_DIR = os.path.join(BASE_DIR,'templates')
    STATIC_DIR = os.path.join(BASE_DIR,'static')
    MEDIA_DIR = os.path.join(BASE_DIR,'media')
    # This is default path from Django, must be added 
    #AFTER our BASE_DIR otherwise DB will be broken.
    BASE_DIR = Path(__file__).resolve().parent.parent
    # add your apps to Installed apps
    INSTALLED_APPS = [
        'main',
        'weblogin',
         ..........
    # Now add TEMPLATE_DIR to  'DIRS' where in TEMPLATES like bellow
    TEMPLATES = [
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [TEMPLATE_DIR, BASE_DIR,],
            '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',
    # On end of Settings.py put this refferences to Static and Media files
    STATICFILES_DIRS = [STATIC_DIR,]
    STATIC_URL = '/static/'
    MEDIA_ROOT = [MEDIA_DIR,]
    MEDIA_URL = '/media/'
    

    If you have problem with Database, please check if you put the original BASE_DIR bellow the new BASE_DIR otherwise change

    # Original
    'NAME': BASE_DIR / 'db.sqlite3',
    'NAME': os.path.join(BASE_DIR,'db.sqlite3'),
    

    Django now will be able to find the HTML and Static files both in the App folders and in Root folder without need of adding the name of App folder in front of the file.

    Struture:
    -DjangoProject
        -static(css,JS ...)
        -templates(base.html, ....)
        -other django files like (manage.py, ....)
        -App1
            -templates(index1.html, other html files can extend now base.html too)
            -other App1 files
        -App2
            -templates(index2.html, other html files can extend now base.html too)
            -other App2 files
    

    Another cause of the "template does not exist" error seems to be forgetting to add the app name in settings.py. I forgot to add it and that was the reason for the error in my case.

    INSTALLED_APPS = [
        'my_app',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [r'C:\Users\islam\Desktop\html_project\django\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',
    

    put the full directory of your templates file, then in views :

    def home(request):
    return render(request, "home\index.html")
    

    start the path that after templates to the html file

    in brief :

    the full path is : C:\Users\islam\Desktop\html_project\django\templates\home\index.html

  • C:\Users\islam\Desktop\html_project\django\templates the full path to your template file will be in TEMPLATES in 'DIRS': [' ']

  • home\index.html the path that comes after template will be in render( )

  •