Какой путь использует Django для поиска и загрузки шаблонов?


91

Я следую этому руководству в среде Windows 7.

В моем файле настроек есть это определение:

TEMPLATE_DIRS = (
    'C:/django-project/myapp/mytemplates/admin'
)

Я получил base_templateиз шаблона admin/base_site.htmlиз каталога шаблонов администратора Django по умолчанию в исходном коде самого Django (django / contrib / admin / templates) в подкаталог admin каталога, myappкак указано в руководстве, но, похоже, это не повлияет по какой-то причине.

Есть какие-нибудь подсказки, в чем может быть проблема?

Ответы:


185

Я знаю, что этого нет в учебнике Django, и позор им, но лучше настроить относительные пути для переменных пути. Вы можете настроить это так:

import os.path

PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))

...

MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media/')

TEMPLATE_DIRS = [
    os.path.join(PROJECT_PATH, 'templates/'),
]

Таким образом вы можете переместить свой проект Django, и корни вашего пути обновятся автоматически. Это полезно при настройке рабочего сервера.

Во-вторых, в вашем пути TEMPLATE_DIRS есть что-то подозрительное. Он должен указывать на корень вашего каталога шаблонов. Кроме того, он также должен заканчиваться трейлингом /.

Я просто собираюсь предположить, что .../admin/каталог не является корнем вашего шаблона. Если вы все еще хотите писать абсолютные пути, вы должны удалить ссылку на каталог шаблонов администратора.

TEMPLATE_DIRS = [
    'C:/django-project/myapp/mytemplates/',
]

При этом загрузчики шаблонов по умолчанию должны быть настроены на рекурсивный переход в каталоги вашего приложения для поиска файлов шаблонов.

TEMPLATE_LOADERS = [
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
    # 'django.template.loaders.eggs.load_template_source',
]

Вам не нужно копировать шаблоны администратора, если вы специально не хотите что-то перезаписывать.

Вам нужно будет запустить syncdb, если вы еще не запустили его. Вам также потребуется статический сервер ваших медиа-файлов, если вы размещаете django через runserver.


1
Большое спасибо, удалив "/ admin" в конце относительного пути TEMPLATE_DIRS.
Shaytac

1
Это предложение помещает каталог шаблонов в папку проекта. Для лучшей организации имеет ли смысл поместить его в папку приложения?
Sahas Katta 02

2
Это устранило мою проблему. Благодарю. НО, в файле настроек по умолчанию был комментарий с TEMPLATE_DIRS, в котором говорилось: «Не забывайте использовать абсолютные пути, а не относительные пути». Кто-нибудь знает обоснование этого комментария?
bhekman

1
PROJECT_PATH - это абсолютный путь к папке проекта. Этот метод устанавливает абсолютный путь к мультимедиа динамически во время выполнения, поэтому значение не жестко запрограммировано и может автоматически меняться в зависимости от местоположения проекта. Это старый пост, но вы можете использовать его для определения местоположения любой папки или файла в проекте.
digitaldreamer

2
Я бы предложил использовать os.path.joinдля добавления путей к базовому каталогу.
антонагестам

35

Если используются установленные настройки Django, то почему бы просто не использовать его встроенные, предопределенные BASE_DIR и TEMPLATES? В пакете установленного Django (v1.8) я получаю:

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


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            ### ADD YOUR DIRECTORY HERE LIKE SO:
            BASE_DIR + '/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',
            ],
        },
    },
]

1
этот «BASE_DIR + '/ templates /',» сделал свое дело. И это выглядит намного изящнее, чем отдельный раздел.
Maxiller

2
использовать os.path.join(BASE_DIR, 'templates') чтобы путь не зависел от платформы.
Abhyudai

12

Умное решение в Django 2.0.3 для хранения шаблонов в каталоге проекта ( /root/templates/app_name):

settings.py

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

в views.py просто добавьте такой путь к шаблону:

app_name/html_name

9

Для Django 1.6.6:

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DIRS = os.path.join(BASE_DIR, 'templates')

Также статические и мультимедийные для режима отладки и производства:

STATIC_URL = '/static/'
MEDIA_URL = '/media/'
if DEBUG:
    STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
else:
    STATIC_ROOT = %REAL_PATH_TO_PRODUCTION_STATIC_FOLDER%
    MEDIA_ROOT = %REAL_PATH_TO_PRODUCTION_MEDIA_FOLDER%

В urls.py необходимо добавить:

from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings

from news.views import Index

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    ...
    )

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

В Django 1.8 вы можете задавать пути к шаблонам, бэкэнд и другие параметры для шаблонов в одном словаре ( settings.py ):

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            path.join(BASE_DIR, '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',
            ],
        },
    },
]

Официальные документы.


Путь к шаблону должен быть кортежем: используйте этот TEMPLATE_DIRS = (os.path.join (BASE_DIR, 'templates'),)
renderbox

6

У меня также были проблемы с этой частью учебника (использовался учебник для версии 1.7).

Моя ошибка заключалась в том, что я редактировал только строку «Администрирование Django» и не уделял должного внимания руководству.

Это строка из django / contrib / admin / templates / admin / base_site.html :

<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>

Но через некоторое время и разочарование стало ясно, что существует оператор site_header или default: _, который следует удалить. Итак, после удаления оператора (как в примере в руководстве, все заработало, как ожидалось).

Пример руководства:

<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>

2

Хорошо 😁 Допустим, у вас есть совершенно новый проект, если вы хотите пойти в settings.pyфайл и TEMPLATESнайти его, просто вставьте эту строку os.path.join(BASE_DIR, 'template')в. 'DIRS'В конце вы должны получить что-то вроде этого:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'template')
        ],
        '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',
            ],
        },
    },
]

Если вы хотите узнать, где находится ваш каталог BASE_DIR, введите эти 3 простые команды:

python3 manage.py shell

Как только вы окажетесь в оболочке:

>>> from django.conf import settings
>>> settings.BASE_DIR

PS: Если вы назвали папку своего шаблона другим именем, вы также измените его здесь.


2

В django 3.1 перейдите к настройке вашего проекта и импортируйте os

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "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',
            ],
        },
    },
]


1

В отличие от некоторых ответов, опубликованных в этой теме, добавление не 'DIRS': ['templates']имеет никакого эффекта (оно избыточно), поскольку templatesэто путь по умолчанию, по которому Django ищет шаблоны.

Если вы пытаетесь сослаться на шаблон приложения, убедитесь, что ваше приложение находится в списке INSTALLED_APPSв основном проекте settings.py.

INSTALLED_APPS': [
   # ...
   'my_app',
]

Цитирование Джанго Шаблоны документов:

класс DjangoTemplates¶

Установите BACKEND на 'django.template.backends.django.DjangoTemplates', чтобы настроить механизм шаблонов Django.

Когда APP_DIRS имеет значение True, движки DjangoTemplates ищут шаблоны в подкаталоге шаблонов установленных приложений. Это общее имя было сохранено для обратной совместимости.

Когда вы создаете приложение для своего проекта, templatesвнутри каталога приложения нет каталога. Поскольку у вас может быть приложение без использования шаблонов, Django не создает такой каталог. То есть вы должны создать его и хранить там свои шаблоны.

Вот еще один абзац из документации Django Tutorial , который еще яснее:

Параметр TEMPLATES вашего проекта описывает, как Django будет загружать и отображать шаблоны. Файл настроек по умолчанию настраивает серверную часть DjangoTemplates, чей параметр APP_DIRS имеет значение True. По соглашению DjangoTemplates ищет подкаталог шаблонов в каждом из INSTALLED_APPS.


1
Хорошо сказано. Стоит упомянуть документацию по шаблонам и то, что в ней говорится о templatesкаталоге.
ivanleoncz

0

в основном BASE_DIRэто каталог вашего проекта django, тот же каталог, где manage.pyнаходится.

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, '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',
                ],
            },
        },
    ]

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.