TemplateDoesNotExist位于/​​(home.html)

时间:2018-03-14 08:32:58

标签: django python-3.x

我正在研究一个示例占位符图像服务器。这使用单一文件方法,因此网址,视图,设置都只在一个名为placeholder.py的文件中。

每当我尝试访问http://localhost:8000(主页)时,我都会TemplateDoesNotExist at /向我投掷。我无法弄清楚出了什么问题。以下是项目结构:

  1. /占位符
    • placeholder.py
    • /模板
      • home.html的
    • /静态
      • 的style.css
  2. 以下是每个文件的内容:

    placeholder.py

    import hashlib
    import os
    import sys
    from io import BytesIO
    from PIL import Image, ImageDraw
    from django.conf import settings
    from django import forms
    from django.urls import path, reverse
    from django.core.cache import cache
    from django.core.wsgi import get_wsgi_application
    from django.http import HttpResponse, HttpResponseBadRequest
    from django.shortcuts import render
    from django.views.decorators.http import etag
    from django.core.management import execute_from_command_line
    
    # settings likely to change between environments
    DEBUG = os.environ.get('DEBUG', 'on') == 'on'
    SECRET_KEY = os.environ.get('SECRET_KEY', 'soj-4^4nho$ifsxsoi1+a8&6o&dya)tcivwcg9g_82&8sg*q^9')
    ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',')
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # settings
    settings.configure(
        DEBUG=DEBUG,
        SECRET_KEY=SECRET_KEY,
        ALLOWED_HOSTS=ALLOWED_HOSTS,
        ROOT_URLCONF=__name__,
        MIDDLEWARE_CLASSES=(
            'django.middleware.common.CommonMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.middleware.clickjacking.XFrameOptionsMiddleware',
        ),
        INSTALLED_APPS=(
            'django.contrib.staticfiles',
        ),
        TEMPLATES=[
            {
                'BACKEND': 'django.template.backends.django.DjangoTemplates',
                'DIRS': os.path.join(BASE_DIR, 'templates'),
            }
        ],
        STATICFILES_DIRS=(
            os.path.join(BASE_DIR, 'static'),
        ),
        STATIC_URL='/static/',
    )
    
    # simple form to validate the height and width of an image
    class ImageForm(forms.Form):
        '''form to validate requested placeholder image'''
        width = forms.IntegerField(min_value=1, max_value=2000)
        height = forms.IntegerField(min_value=1, max_value=2000)
    
        def generate(self, image_format='PNG'):
            '''generate an image of the given type and return as raw bytes'''
            width = self.cleaned_data['width']
            height = self.cleaned_data['height']
            key = '{}.{}.{}'.format(width, height, image_format)
            content = cache.get(key)
            if content is None:    
                image = Image.new('RGB', (width, height))
                draw = ImageDraw.Draw(image)
                text = '{} x {}'.format(width, height)
                textwidth, textheight = draw.textsize(text)
                if textwidth < width and textheight < height:
                    texttop = (height - textheight) // 2
                    textleft = (width - textwidth) // 2
                    draw.text((textleft, texttop), text, fill=(255, 255, 255))
                content = BytesIO()
                image.save(content, image_format)
                content.seek(0)
                cache.set(key, content, 60 * 60)
            return content
    
    # for client-side caching
    def generate_etag(request, width, height):
        content = 'Placeholder: {0} x {1}'.format(width, height)
        return hashlib.sha1(content.encode('utf-8')).hexdigest()
    
    # views
    def index(request):
        example = reverse('placeholder', kwargs={'width':50, 'height':50})
        context = {
            'example' : request.build_absolute_uri(example)
        }
        return render(request, 'home.html', context)
    
    @etag(generate_etag) # decorator for client-side caching
    def placeholder(request, width, height):
        form = ImageForm({'width':width, 'height':height})
        if form.is_valid():
            image = form.generate()
            return HttpResponse(image, content_type='image/png')
        else:
            return HttpResponseBadRequest('<h1>Invalid Image Request!</h1>')
    
    # the url
    urlpatterns = [
        path('', index, name='homepage'),
        path('image/<int:width>x<int:height>', placeholder, name='placeholder'),
    ]
    
    # wsgi application
    application = get_wsgi_application()
    
    # relevant part from manage.py
    if __name__ == "__main__":
        execute_from_command_line(sys.argv)
    

    home.html

    {% load static %}
    
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>Demo Placeholder Images</title>
            <link type="text/css" rel="stylesheet" href="{% static 'style.css' %}">
        </head>
        <body>
            <h1>Demo Placeholder Images</h1>
            <p>This server can be used for serving placeholder images for any webpage.</p>
            <p>To request a placeholder image of a given width and height simply include
                an image with the source pointing to <b>/placeholder/&lt;width&gt;x
                    &lt;height&gt;/</b> on this server such as:
            </p>
            <pre>&lt;img src="{{ example }}"&gt;</pre>
            <h2>Examples</h2>
            <ul>
                <li><img src="{% url 'placeholder' width=50 height=50 %}"></li>
                <li><img src="{% url 'placeholder' width=100 height=50 %}"></li>
                <li><img src="{% url 'placeholder' width=50 height=100 %}"></li>
            </ul>
        </body>
    </html>
    

    出了什么问题?

2 个答案:

答案 0 :(得分:0)

我认为问题是您的BASE_DIR不正确。因为您有一个简单的平面文件,并且模板和静态文件位于同一级别的子目录中,所以您只需要转到当前目录,而不是父目录。所以它应该是:

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

答案 1 :(得分:0)

我明白了。 'DIRS'设置中TEMPLATES的值应为列表。这就是我的意思:

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