Django "TemplateDoesNotExist " Error but "Using loader django.template.loaders.app_directories.Loader" File Exists Django "TemplateDoesNotExist " Error but "Using loader django.template.loaders.app_directories.Loader" File Exists django django

Django "TemplateDoesNotExist " Error but "Using loader django.template.loaders.app_directories.Loader" File Exists


i've been running into the same problem, the solution that work was to specify my template directory (projects/templates) in templates settings like this:

TEMPLATES = [{    'BACKEND': 'django.template.backends.django.DjangoTemplates',    'DIRS': ['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',            "django.core.context_processors.media",        ],    },},

]


TemplateDoesNotExist... cardpayment.html might mean Django can't find cardpayment.html, or it might mean it can find cardpayment.html no problem, but can't find some {% include 'cardpayment_subsection.html' %} within it.

Explanation:

I got this error just now, in a project that's been working for years, and the other solutions here didn't help me.

My cardpayment.html was being found by the template loaders, but contained some nonsense which meant it could not be rendered.The error messages mislead me into thinking Django didn't know the file exists, when in fact it knew it existed, just couldn't successfully render it.

For a while everything was working fine: cardpayment.html was being rendered without a problem.

views.py

def cardpaymentview(request):                return render_to_response("cardpayment.html", {            "message": "Hi SO"            }, context_instance=RequestContext(request))

Suddenly, even though I hadn't been editing cardpayment.html, I got that error:

TemplateDoesNotExist at /cardpaymentpage:cardpayment.html

Using loader django.template.loaders.app_directories.Loader:folder/lib/python2.7/site-packages/django/contrib/admin/templates/cardpayment.html (File does not exist)folder/project/app1/templates/cardpayment.html (File does not exist)folder/project/app2/templates/cardpayment.html (File does not exist)folder/project/paymentapp/templates/cardpayment.html (File exists)

The problem was that my cardpayment.html in turn has an include calling another template:

{% include 'cardpayment_subsection.html' %}

I created the error by renaming the file cardpayment_subsection.html to something_else.html, without editing cardpayment.html, so that include command naturally failed.

But as you can see, the debug message didn't indicate the problem was callling the cardpayment_subsection.html (file no longer exists).

Summary: if other solutions don't work for you, try creating a test file cardpayment2.html that simply says "Hello world" and see if you can at least render that instead. Maybe the cardpayment.html file is being read, but has an error within it. (In my case, I needed to change the {% include '____.html' %} to refer to a file that actually does exist!)


I'm also using the DIRS config option in a similar way to you and I've just run into the same problem in Django 1.8.2. The issue seems to relate to the way you invoke django.shortcuts.render (or django.shortcuts.render_to_response) in your views - are you using these?

TL;DR - try changing your invocation of render_to_response in your views so that you don't pass a context_instance or any deprecated argument, such as the previously often used django.template.RequestContext. If you do pass a context_instance, or any deprecated argument, the django template loading code uses a legacy path that doesn't support the DIRS option and your template will not be loaded - even if it exists on disk.

Here's a section of relevant code from the Django source (django/shortcuts.py) that shows how this situation comes about:

def render_to_response(template_name, context=None,                       context_instance=_context_instance_undefined,                       content_type=None, status=None, dirs=_dirs_undefined,                       dictionary=_dictionary_undefined, using=None):    """    Returns a HttpResponse whose content is filled with the result of calling    django.template.loader.render_to_string() with the passed arguments.    """    if (context_instance is _context_instance_undefined            and dirs is _dirs_undefined            and dictionary is _dictionary_undefined):        # No deprecated arguments were passed - use the new code path        content = loader.render_to_string(template_name, context, using=using)    else:        # Some deprecated arguments were passed - use the legacy code path        content = loader.render_to_string(            template_name, context, context_instance, dirs, dictionary,            using=using)    return HttpResponse(content, content_type, status)

If you follow this through to the loader's render_to_string method (in django/template/loader.py) you can see your template won't be loaded if you pass any deprecated arguments to render_to_reponse in your views:

def render_to_string(template_name, context=None,                     context_instance=_context_instance_undefined,                     dirs=_dirs_undefined,                     dictionary=_dictionary_undefined,                     request=None, using=None):    """    Loads a template and renders it with a context. Returns a string.    template_name may be a string or a list of strings.    """    if (context_instance is _context_instance_undefined            and dirs is _dirs_undefined            and dictionary is _dictionary_undefined):        # No deprecated arguments were passed - use the new code path        if isinstance(template_name, (list, tuple)):            template = select_template(template_name, using=using)        else:            template = get_template(template_name, using=using)        return template.render(context, request)    else:        # Some deprecated arguments were passed - use the legacy code path        for engine in _engine_list(using):            try:                # This is required for deprecating properly arguments specific                # to Django templates. Remove Engine.render_to_string() at the                # same time as this code path in Django 2.0.                if isinstance(engine, DjangoTemplates):                    if request is not None:                        raise ValueError(                            "render_to_string doesn't support the request argument "                            "when some deprecated arguments are passed.")                        continue                    # Hack -- use the internal Engine instance of DjangoTemplates.                    return engine.engine.render_to_string(                        template_name, context, context_instance, dirs, dictionary)                elif context_instance is not _context_instance_undefined:                    warnings.warn(                        "Skipping template backend %s because its render_to_string "                        "method doesn't support the context_instance argument." %                        engine.name, stacklevel=2)                elif dirs is not _dirs_undefined:                    warnings.warn(                        "Skipping template backend %s because its render_to_string "                        "method doesn't support the dirs argument." % engine.name,                        stacklevel=2)                elif dictionary is not _dictionary_undefined:                    warnings.warn(                        "Skipping template backend %s because its render_to_string "                        "method doesn't support the dictionary argument." %                        engine.name, stacklevel=2)            except TemplateDoesNotExist:                continue        if template_name:            if isinstance(template_name, (list, tuple)):                template_name = ', '.join(template_name)            raise TemplateDoesNotExist(template_name)        else:            raise TemplateDoesNotExist("No template names provided")