Django通用视图的正确模板位置?

5 投票
1 回答
623 浏览
提问于 2025-04-20 21:43

根据Django文档,模板加载器会

从Django应用的文件系统中加载模板。对于每个在INSTALLED_APPS中的应用,加载器会查找一个名为templates的子目录。

继续说:

...然后get_template('foo.html')会按照以下顺序在这些目录中查找foo.html:

/path/to/myproject/polls/templates/
/path/to/myproject/music/templates/

所以...在我的"website"项目中,我有一个"www"应用。目录结构是/path/to/project/website/www/

我在"www"里面创建了一个"templates"目录,并在里面放了"page_list.html"(/path/to/project/website/www/page_list.html

这个应用在"INSTALLED_APPS"中列出,但当我在urls.py中尝试这样做时:

url('^$', ListView.as_view(model=Page,))

我得到了"TemplateDoesNotExist"的错误,错误信息说django.template.loaders.app_directories.Loader正在寻找"/path/to/project/website/templates/www/page_list.html"或者/path/to/project/website/www/templates/www/page_list.html

如果我把模板放在website/www/templates/www里面,它就能正常工作...但我想知道为什么会这样。把一个templates文件夹放在应用文件夹里面,然后在templates目录里面再有一个同名的文件夹,听起来有点荒谬....

而且文档说应该在project/app/templates里面查找...我确实有

TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]

虽然关于app_directories.Loader的文档没有说你需要这样做(我也尝试过去掉那个选项)。

这是怎么回事?我是不是做错了什么?是关于通用视图的事,还是还有其他问题?

1 个回答

5

你的问题是关于Django中基于类的视图自动命名模板的。比如,当你使用 django.views.generic.ListView 时,它会给你的模板自动生成一个名字 www/poll_list.html。这个名字是通过 MultipleObjectTemplateResponseMixin 创建的。这个模板名是和 app_directory Loader 生成的前缀结合在一起的,所以你最终得到的路径是 /path/to/project/app/templates/www/poll_list.html

如果你不想要这个自动生成的名字,有几种不同的选择(按顺序):

  • 在你的视图中使用 template_name 参数或属性。
  • 创建一个 MultipleObjectTemplateResponseMixin 的子类,并去掉应用的前缀。然后在你的视图中使用这个子类。
  • 不使用 app_directory loader。

撰写回答