Django多 app 同名 模版 引用错误的问题

问题描述:Django项目中,多个app下有同名DTL模板,引用模板不正确的问题。

环境:

>python --version
Python 3.7.1

>python -m django --version
2.1.4

目录结构(部分文件已省略):

│  manage.py
│
├─apps
│  │  __init__.py
│  │
│  ├─app03
│  │  │  urls.py
│  │  │  views.py
│  │  │  __init__.py
│  │  │
│  │  ├─templates
│  │  │  index.html
│  │  └─...
│  │
│  ├─app04
│  │  │  urls.py
│  │  │  views.py
│  │  │  __init__.py
│  │  │
│  │  ├─templates
│  │  │  index.html
│  │  └─...
│  └─...
│
├─djangostart
│  │  settings.py
│  │  urls.py
│  │  wsgi.py
│  │  __init__.py
│  │
│  └─...
│
└─templates
       ...

djangostart/urls.py文件中配置:

# namespace是实例命名空间,在这里去掉也不影响;
# 但注意使用实例命名空间之前一定要在app的`urls.py`文件中配置应用(app)命名空间。
path('app03/', include('apps.app03.urls', namespace='app03')),
path('app04/', include('apps.app04.urls')),

apps/app04/urls.py文件中配置:

path('', views.index),

apps/app04/views.py文件中:

def index(request):
    context = {
        'value': 'onefine',
    }
    return render(request, 'index.html', context=context)

apps/app04/templates/index.html中:

{% load self_filter %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app04-index.html</title>
</head>
<body>
    {{ value|my_filter:"hello" }}
</body>
</html>

djangostart/settings.py中配置:

...
INSTALLED_APPS = [
	...
    'apps.app03',
    'apps.app04',
    # 我尝试过交互这两个app的安装顺序,结果是先安装的访问引用的模板正常,而后按照的访问就不正常。
]

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',
            ],
        },
    },
]
...

运行服务,访问 http://127.0.0.1:8000/app04/
在这里插入图片描述

但引用的却是apps/app03/templates/index.html的DTL模板。

按照我的理解,DTL模板的查找顺序应该是:比如代码render('index.html')。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有就返回。如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经安装,如果已经安装了,那么就先在当前这个app下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径下都没有找到,那么会抛出一个TemplateDoesNotExist异常。

我的代码apps/app04/templates/中有index.html模板,但为什么引用的却是apps/app03/templates/下面的模板。

百思不得其解… 虽然已经找到下面的解决方法,但还是不知道为什么这样,先记录一下


解决办法:

1、在app下新建文件夹templates,在templates里面建立app同名文件夹,再放入DTL模板。
2、引用模版的时候,采用<appname>/index.html这种方式。

完成之后目录结构(部分文件已省略):

│  manage.py
│
├─apps
│  │  __init__.py
│  │
│  ├─app03
│  │  │  urls.py
│  │  │  views.py
│  │  │  __init__.py
│  │  │
│  │  ├─templates
│  │  │  └─app03
│  │  │          index.html
│  │  │
│  │  └─...
│  │
│  ├─app04
│  │  │  urls.py
│  │  │  views.py
│  │  │  __init__.py
│  │  │
│  │  ├─templates
│  │  │  └─app04
│  │  │          index.html
│  │  └─...
│  │
│  └─...
│
├─djangostart
│  │  settings.py
│  │  urls.py
│  │  wsgi.py
│  │  __init__.py
│  │
│  └─...
│
└─templates
       ...

重新运行服务,访问 http://127.0.0.1:8000/app04/
在这里插入图片描述

现在倒是正常了。


PS: 如果有大佬知道原因,希望不吝赐教!


参考:
Django 多 app 同名 模版 引用: https://blog.csdn.net/u013205877/article/details/77278777?utm_source=blogxgwz4

注:在被参考的博客中已经找到些思路,但是还不是特别明确,比如里面提到修改Django模板的载入模式:APP_DIRS的值设置为True,同时将DIRS设置为空,表示启用django.template.loaders.app_directories.Loader,DIRS——它会从app对应的templates目录中查找要渲染的模板文件,即使找不到也不去其他app里面找。

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',
            ],
        },
    },
]

运行服务,访问: http://127.0.0.1:8000/app04/
在这里插入图片描述
还是不正常!


原文地址:https://www.cnblogs.com/onefine/p/10499345.html