アプリケーションディレクトリにテンプレート用ディレクトリを作成して、アプリケーション単位でテンプレートを管理する方法をネットで調べました。 しかし、思うようなものが見つからなかったので、個人的にいろいろと試してみました。 このページのその試した結果をまとめたものです。
このページでは、以下のようなプロジェクト名やアプリケーション名とします。
- プロジェクト名: mysite
- アプリケーション名: app
- テンプレート用ディレクトリ名: templates
/vagrant/www/mysite/app/templates
テンプレートファイル名が "index.html" の場合、絶対パスは以下になります。
/vagrant/www/mysite/app/templates/index.htmlまた、別のアプリケーションwordsのテンプレートも同じように用意します。
/vagrant/www/mysite/words/templates/index.html
絶対パスでテンプレートファイルを指定
テンプレートファイルは絶対パスを指定することが可能です。 絶対パスで指定する場合、settings.pyのTEMPLATESはデフォルトのままで大丈夫です。
pathlibモジュール
pathlibモジュールと __file__を使って、アプリケーションディレクトリの絶対パスを取得します。 それをもとにテンプレートファイルの絶対パスを指定します。
例 mysite/app/view.py
from django.shortcuts import render
from pathlib import Path
# Create your views here.
def index(request):
tpl = Path.joinpath(Path(__file__).parent, 'templates').joinpath('index.html')
return render(request, tpl)
指定が複数ある場合、テンプレートディレクトリを以下のように定義すると便利です。
tpl_dir = Path.joinpath(Path(__file__).parent, 'templates')
例 mysite/app/view.py
from django.shortcuts import render from pathlib import Path tpl_dir = Path.joinpath(Path(__file__).parent, 'templates') # Create your views here. def index(request): return render(request, tpl_dir.joinpath('index.html'))
osモジュール
osモジュールと __file__を使って、アプリケーションディレクトリの絶対パスを取得します。 それをもとにテンプレートファイルの絶対パスを指定します。
ただし、osモジュールを使うとパス取得が長くるので、アプリケーションディレクトリをAPP_DIR、テンプレートディレクトリをTPL_DIRとして定義しています。
例 mysite/app/view.py
from django.shortcuts import render import os APP_DIR = os.path.dirname(os.path.abspath(__file__)) TPL_DIR = os.path.join(os.path.join(APP_DIR, os.path.join('templates')), '') # Create your views here. def index(request): return render(request, TPL_DIR + 'index.html')注意 TPL_DIRは最後にパス区切り文字を付けているので、APP_DIRとTPL_DIRは以下のようになります。
APP_DIR = "/vagrant/www/mysite/app" TMP_DIR = "/vagrant/www/mysite/app/templates/"
相対パスでテンプレートファイルを指定
相対パスを使う場合、settings.pyの TEMPLATES のDIRSの指定が必要です。 ここでは空文字を指定して、プロジェクトディレクトリがテンプレートのトップディレクトリにします。 ビューではアプリケーションディレクトリからの相対パスを指定します。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [''],
'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を指定する方法もあります。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR],
'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',
],
},
},
]
アプリケーション名を直接指定
テンプレートの数が少ない場合、直接アプリケーション名を指定するのが簡単です。
例 mysite/app/view.py
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, 'app/templates/index.html')
アプリケーション名をrequestから取得
アプリケーション名変更の可能性がある場合など、汎用性を求める場合はアプリケーション名を自動取得するようにします。 もっと良い方法があると思いますが見つからなかったので、ここではrequest.resolver_match.routeを使った方法になります。
request.resolver_match.routeはURLのパスを取得できますので、それをアプリケーション名に使用します。 アクセスURLが"http://example.com/app/"の場合、request.resolver_match.route は "app/" になります。 これを使って以下のように指定すると、アプリケーションディレクトリが先頭の相対パスが指定できます。
request.resolver_match.route + '[テンプレート名]/[テンプレートファイル名]
例 mysite/app/templates/view.py
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, request.resolver_match.route + 'templates/index.html'')
参考 上記のテンプレート指定は 'app/templates/index.html' となります。