Django视图 - 首先从应用程序的目录调用模板 [英] Django view - load template from calling app's dir first
问题描述
有没有办法请始终在通话应用程序的模板 c>目录中检查一个匹配项。
我的 settings.py
:
PROJECT_PATH = os.path.realpath(os.path.dirname __file__))
TEMPLATE_LOADERS =(
'django.template.loaders.app_directories.load_template_source',
'django.template.loaders.filesystem.load_template_source',
)
TEMPLATE_DIRS =(
os.path.join(PROJECT_PATH,'templates'),
)
我尝试更改 TEMPLATE_LOADERS
的顺序,没有成功。
按照Ashok的要求进行编辑:
每个应用程序的目录结构:
templates /
index.html
add.html
delete.html
create.html
models.py
test.py
admin.py
views.py
在每个应用的views.py中:
def index (请求):
#代码...
返回render_to_response('index.html',本地())
def add(request):
#code ...
return render_to_response('add.html',locals())
def delete(request):
#code ...
return render_to_response 'delete.html',locals())
def update(request):
#code ...
return render_to_response('update.html',locals())
原因是app_directories装载器本质上与将每个应用程序的模板文件夹添加到TEMPLATE_DIRS设置相同,例如像
TEMPLATE_DIRS =(
os.path.join(PROJECT_PATH,'app1','templates'),
os.path.join(PROJECT_PATH,'app2','template'),
...
os.path.join(PROJECT_PATH,'templates'),
)
这个问题是,正如你所提到的,index.html将始终在app1 / templates中找到/index.html,而不是任何其他应用程序。在没有修改app_directories加载程序并使用内省或传递应用程序信息的情况下,没有任何简单的解决方案来神奇地修复此行为,这有点复杂。一个更容易的解决方案:
- 保持您的settings.py原样
- 每个添加一个子目录使用应用程序名称的应用程序模板文件夹
- 在app1 / index.html或app2 / index.html视图中使用模板
有一个更具体的例子:
project
app1
模板
app1
index.html
add.html
...
models.py
views.py
。 ..
app2
...
然后在视图中:
def index(request):
return render_to_response('app1 / index.html',locals())
你甚至可以编写一个包装器来自动化将应用名称添加到所有视图中,甚至可以扩展到使用内省,例如:
def render(template,data = None) :
return render_to_response(__ name __。split(。)[ - 2] +'/'+ template,data)
def index(request):
return render 'index.html',locals())
_____名_____。split(。)[ - 2]假定文件在一个包中,所以它会转动例如'app1.views'添加到'app1'中以添加到模板名称。这也假设用户永远不会重命名您的应用程序,而不需要重命名templates目录中的文件夹,这可能不是一个安全的假设,而在这种情况下,只需对templates目录中的文件夹的名称进行硬编码。
I try to keep a somewhat consistent naming scheme on my HTML templates. I.e. index.html for main, delete.html for delete page and so forth. But the app_directories
loader always seems to load the template from the app that's first alphabetically.
Is there any way to always check for a match in the calling app's templates
directory first?
Relevant settings in my settings.py
:
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.load_template_source',
'django.template.loaders.filesystem.load_template_source',
)
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates'),
)
I've tried changing the order of TEMPLATE_LOADERS
, without success.
Edit as requested by Ashok:
Dir structure of each app:
templates/
index.html
add.html
delete.html
create.html
models.py
test.py
admin.py
views.py
In each app's views.py:
def index(request):
# code...
return render_to_response('index.html', locals())
def add(request):
# code...
return render_to_response('add.html', locals())
def delete(request):
# code...
return render_to_response('delete.html', locals())
def update(request):
# code...
return render_to_response('update.html', locals())
The reason for this is that the app_directories loader is essentially the same as adding each app's template folder to the TEMPLATE_DIRS setting, e.g. like
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'app1', 'templates'),
os.path.join(PROJECT_PATH, 'app2', 'template'),
...
os.path.join(PROJECT_PATH, 'templates'),
)
The problem with this is that as you mentioned, the index.html will always be found in app1/templates/index.html instead of any other app. There is no easy solution to magically fix this behavior without modifying the app_directories loader and using introspection or passing along app information, which gets a bit complicated. An easier solution:
- Keep your settings.py as-is
- Add a subdirectory in each app's templates folder with the name of the app
- Use the templates in views like 'app1/index.html' or 'app2/index.html'
For a more concrete example:
project
app1
templates
app1
index.html
add.html
...
models.py
views.py
...
app2
...
Then in the views:
def index(request):
return render_to_response('app1/index.html', locals())
You could even write a wrapper to automate prepending the app name to all your views, and even that could be extended to use introspection, e.g.:
def render(template, data=None):
return render_to_response(__name__.split(".")[-2] + '/' + template, data)
def index(request):
return render('index.html', locals())
The _____name_____.split(".")[-2] assumes the file is within a package, so it will turn e.g. 'app1.views' into 'app1' to prepend to the template name. This also assumes a user will never rename your app without also renaming the folder in the templates directory, which may not be a safe assumption to make and in that case just hard-code the name of the folder in the templates directory.
这篇关于Django视图 - 首先从应用程序的目录调用模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!