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

前端 未结 7 1850
我在风中等你
我在风中等你 2021-01-05 19:05

Template Loader finds the template but template is not loaded

TemplateDoesNotExist at /cardpayment/

cardpayment.html

Request Method:     G         


        
相关标签:
7条回答
  • 2021-01-05 19:34

    Find settings.py in your python project and add following line. I hope it will work

    SETTINGS_PATH = os.path.normpath(os.path.dirname(__file__))
    TEMPLATE_DIRS = (
       os.path.join(SETTINGS_PATH, 'templates'),
    )
    
    0 讨论(0)
  • 2021-01-05 19:36

    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")
    
    0 讨论(0)
  • 2021-01-05 19:37

    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",
            ],
        },
    },
    

    ]

    0 讨论(0)
  • 2021-01-05 19:42

    Django’s template system was overhauled in Django 1.8 when it gained support for multiple template engines.

    The TEMPLATES settings

    A new setting was introduced in Django 1.8: TEMPLATES. All existing template-related settings were deprecated.

    During the deprecation period, Django will create a backwards-compatible TEMPLATES based on the TEMPLATE_* settings if you don’t define it yourself.

    Here’s how to define TEMPLATES in your settings module.

    If you’re using the default value of TEMPLATE_LOADERS, that is, if it isn’t defined in your settings file or if it’s set to:

    ['django.template.loaders.filesystem.Loader',
     'django.template.loaders.app_directories.Loader']
    

    then you should define TEMPLATES as follows:

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [
                # insert your TEMPLATE_DIRS here
            ],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
                    # list if you haven't customized them:
                    'django.contrib.auth.context_processors.auth',
                    'django.template.context_processors.debug',
                    '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',
                ],
            },
        },
    ]
    

    More information can be found here https://docs.djangoproject.com/en/1.11/ref/templates/upgrading/

    0 讨论(0)
  • 2021-01-05 19:44

    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!)

    0 讨论(0)
  • 2021-01-05 19:44

    I had the same problem and it was solved after changing the order of the apps in INSTALLED_APPS in the settings.py file.
    Put your app's name first on the list:

    INSTALLED_APPS = [
        'module_name',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]
    
    0 讨论(0)
提交回复
热议问题