Django模板加载器的行为?(得到Django TemplateDoesNotExist异常)

Kie*_*ran 2 python django django-templates

文件夹结构

我目前正在从Django书中学习Django.我有以下目录结构:

.
??? mysite
    ??? books
    ?   ??? __init__.py
    ?   ??? models.py
    ?   ??? templates
    ?   ?   ??? search_form.html
    ?   ?   ??? search_results.html
    ?   ??? tests.py
    ?   ??? views.py
    ??? contact
    ?   ??? forms.py
    ?   ??? __init__.py
    ?   ??? templates
    ?   ?   ??? contact_form.html
    ?   ??? views.py
    ??? manage.py
    ??? mysite
        ??? __init__.py
        ??? settings.py
        ??? templates
        ?   ??? base.html
        ?   ??? current_datetime.html
        ?   ??? hours_ahead.html
        ??? urls.py
        ??? views.py
        ??? wsgi.py
Run Code Online (Sandbox Code Playgroud)

书籍,联系人和mysite是文件夹.我还为每个文件夹都有一个单独的模板子文件夹来存储模板.

故事

现在,在/mysite/settings.py中,我有以下几行:

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), 'templates').replace('\\', '/'),
)
Run Code Online (Sandbox Code Playgroud)

/contact/views.py里面,我有以下行(注意这里的渲染来自django.shortcuts):

return render(request, 'contact_form.html', {'form': form})
Run Code Online (Sandbox Code Playgroud)

但是,上面的行给了我一个TemplateDoesNotExist异常.这是因为模板加载器在/ mysite/templates /而不是/ contact/templates /下查找文件contact_form.html .

很公平,即使我不明白为什么会这样.但是,我有另一种情况,它表现不同.

回想一下上面的文件结构,我也有books/views.py.在其中,我有以下几行(在不同的逻辑块中):

return render(request, 'search_results.html',
                {'books': books, 'query': q})
Run Code Online (Sandbox Code Playgroud)

return render(request, 'search_form.html', {'errors': errors})
Run Code Online (Sandbox Code Playgroud)

如果回顾上面的内容,search_results.html和search_form.html位于/ books/templates /文件夹下,而不是/ mysite/templates /文件夹,但模板加载器设法找到这些文件.请注意,即使我将search_results.html和search_form.html移至/ mysite/templates /,它仍然有效.

所以我的问题是,为什么加载器寻找模板的位置有所不同?

无论如何,这是我的/contact/views.py看起来像:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.mail import send_mail
from forms import ContactForm
import os

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            send_mail(
                    cd['subject'],
                    cd['message'],
                    cd.get('email', 'noreply@example.com'),
                    ['siteowner@example.com'],
            )
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm()
    print os.path.join(os.path.dirname(__file__), 'templates')
    return render(request, 'contact_form.html', {'form': form})
Run Code Online (Sandbox Code Playgroud)

这是我的/books/views.py:

from django.shortcuts import render
from django.http import HttpResponse
from books.models import Book


def search(request):
    errors = []
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            errors.append('Enter a search term.')
        elif len(q) > 20:
            errors.append('Please enter at most 20 characters.')
        else:
            books = Book.objects.filter(title__icontains=q)
            return render(request, 'search_results.html',
                {'books': books, 'query': q})
    return render(request, 'search_form.html', {'errors': errors})
Run Code Online (Sandbox Code Playgroud)

Yuj*_*ita 6

既然你显然做安装该应用目录模板加载器,而且由于它可以在你的books应用程序,我只能认为你没有contactsettings.INSTALLED_APPS.