Django视图 - 首先从应用程序的目录调用模板 [英] Django view - load template from calling app's dir first

查看:96
本文介绍了Django视图 - 首先从应用程序的目录调用模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的HTML模板上保持一些一致的命名方案。即index.html为主,delete.html为删除页面等。但是,$ code> app_directories 加载器总是似乎从首字母顺序的应用程序加载模板。



有没有办法请始终在通话应用程序的模板 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆