Cookiecutter Django中ListView与View模板目录路径不一致问题排查
Django模板路径不一致问题
Cookiecutter自动在my_project目录生成了users应用,我把自定义应用my_app放在同一目录并加入INSTALLED_APPS,应用能正常运行。但模板存放路径出现了奇怪的问题:
- 一开始参照
users的结构,把模板放在my_project/templates/my_app/下,用普通View时会报TemplateDoesNotExistError;移到my_project/my_app/templates/后,View能正常工作。 - 但用
ListView时又报错,把模板移回my_project/templates/my_app/才生效。
我想统一模板存放目录,但切换路径就报错,以下是相关配置:
目录结构
- requirements - my_project - contrib - sites - migrations - static - css - fonts - images - favicons - js - templates - account - pages - my_app - item_list.html <- 仅在此处生效(ListView) - users - my_app - migrations - templates - item_detail.html <- 仅在此处生效(View) - users - migrations - tests - utils
settings/base.py 配置
ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent APPS_DIR = ROOT_DIR / "my_project" INSTALLED_APPS = [ ... "my_project.users", "my_project.my_app", ... ] TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [str(APPS_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.template.context_processors.i18n", "django.template.context_processors.media", "django.template.context_processors.static", "django.template.context_processors.tz", "django.contrib.messages.context_processors.messages", "my_project.users.context_processors.allauth_settings", ], }, } ]
my_project/my_app/apps.py 配置
from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ class MyAppConfig(AppConfig): # default_auto_field = "django.db.models.BigAutoField" name = "my_project.my_app" verbose_name = _("My_App") # 实际名称不是这个,懂意思就行 def ready(self): try: import my_project.my_app.signals # noqa F401 except ImportError: pass
我试过把my_project.my_app.apps.MyAppConfig加入INSTALLED_APPS,但问题依旧,请问我遗漏了什么配置?
问题原因及解决办法
核心原因
Django查找模板的逻辑和视图里指定模板名称的写法直接相关:
- 当
APP_DIRS=True时,Django会自动扫描每个已安装应用的templates子目录,查找路径为应用目录/templates/模板名。 DIRS配置的全局模板目录优先级更高,Django会先在这里查找应用名/模板名格式的路径。
你的问题本质是视图模板名称写法不统一:
- 普通
View如果写的是template_name = "item_detail.html",Django会先在全局templates目录找该文件,找不到才去my_app/templates/下找,所以放在应用内模板目录能生效。 ListView默认模板名是应用名/模型名_list.html(比如my_app/item_list.html),Django会优先去全局templates/my_app/下匹配这个路径,所以放在那里才生效。
统一模板目录的两种方案
方案1:统一使用全局my_project/templates/my_app/目录
把所有模板都移到这个目录,然后修改视图的模板名称:
- 普通
View:将template_name改为"my_app/item_detail.html" ListView保持默认(或显式写"my_app/item_list.html"),和全局目录结构匹配。
方案2:统一使用应用内my_project/my_app/templates/my_app/目录
注意要在应用的templates目录下再建一个my_app子目录(和全局模板的结构对齐),然后:
- 普通
View:设置template_name = "my_app/item_detail.html" ListView保持默认,Django会自动匹配my_app/templates/my_app/item_list.html路径。
两种方案都能实现模板目录统一,避免切换路径报错。
额外检查点
- 确认
TEMPLATES配置里的APP_DIRS=True没有被注释,这是Django自动查找应用内模板的关键开关。 - 如果使用自定义
AppConfig,确保INSTALLED_APPS里写的是"my_project.my_app.apps.MyAppConfig",显式指定配置类能避免应用识别异常。
内容的提问来源于stack exchange,提问作者ron_g
相关产品推荐
相关产品推荐

