【问题标题】:What is the path that Django uses for locating and loading templates?Django 用于定位和加载模板的路径是什么?
【发布时间】:2011-03-03 13:55:49
【问题描述】:

我在 Windows 7 环境中关注此tutorial

我的设置文件有这个定义:

TEMPLATE_DIRS = (
    'C:/django-project/myapp/mytemplates/admin'
)

我从 Django 本身的源代码 (django/contrib/admin/templates) 的默认 Django 管理模板目录中的模板 admin/base_site.html 中获得了 base_templatemyapp 目录的管理子目录中作为教程已指示,但由于某种原因似乎没有生效。

任何线索可能是什么问题?

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    默认情况下,django 在应用程序中查找模板文件夹。但是如果你想使用项目根目录下的模板文件夹,请在项目根目录下创建一个模板文件夹,并在settings.py中进行如下操作:

    import os
    
    TEMPLATE_DIR = os.path.join(BASE_DIR, "templates")
    TEMPLATES = [
       {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [TEMPLATE_DIR],
        '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',
                ],
            },
        },
    ]
    

    【讨论】:

      【解决方案2】:

      你可以很容易地在settings.py文件夹中添加模板文件夹,os.path在django 3.1中被弃用了,所以你可以使用path来代替os.path。您只需在 settings.py 中导入路径,您必须指定基本目录,然后您必须指定模板路径,最后但并非最不重要的一点是,您必须在 TEMPLATES = [{}] 中添加模板文件夹路径,对于示例:

      from pathlib import Path
      
      BASE_DIR = Path(__file__).resolve().parent.parent
      
      TEMPLATE_DIR = Path(BASE_DIR, 'templates') (you can name TEMPLATE_DIR to any name)
      
      TEMPLATES = [
      {
      
          'BACKEND': 'django.template.backends.django.DjangoTemplates',
      
          'DIRS': [TEMPLATE_DIR],
      
          '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',
      
              ],
          },
      },
      

      ]

      【讨论】:

        【解决方案3】:

        与此线程中发布的一些答案相反,添加 'DIRS': ['templates'] 无效(这是多余的),因为 templates 是 Django 查找模板的默认路径。

        如果您尝试引用应用的模板,请确保您的应用位于主项目settings.pyINSTALLED_APPS 列表中。

        INSTALLED_APPS': [
           # ...
           'my_app',
        ]
        

        引用 Django 的 Templates 文档:

        类 DjangoTemplates¶

        将 BACKEND 设置为 'django.template.backends.django.DjangoTemplates' 以配置 Django 模板引擎。

        当 APP_DIRS 为 True 时,DjangoTemplates 引擎会寻找模板 在已安装应用程序的 templates 子目录中。保留此通用名称是为了向后兼容。

        当您为项目创建应用程序时,应用程序目录中没有templates 目录。 Django admin 默认不会为你创建目录。

        下面是 Django Tutorial 文档中的另一段,更清楚:

        您项目的 TEMPLATES 设置描述了 Django 将如何加载和呈现模板。默认设置文件配置一个 DjangoTemplates 后端,其 APP_DIRS 选项设置为 True。按照惯例,DjangoTemplates 在每个 INSTALLED_APPS 中查找“模板”子目录。

        【讨论】:

        • 说得好。值得一提的是模板文档以及它对templates 目录的说明。
        【解决方案4】:

        我知道这不在 Django 教程中,并且对它们感到羞耻,但最好为路径变量设置相对路径。你可以这样设置:

        import os.path
        
        PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
        
        ...
        
        MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media/')
        
        TEMPLATE_DIRS = [
            os.path.join(PROJECT_PATH, 'templates/'),
        ]
        

        这样你可以移动你的 Django 项目并且你的路径根目录会自动更新。这在您设置生产服务器时很有用。

        其次,您的 TEMPLATE_DIRS 路径有问题。它应该指向模板目录的根目录。此外,它还应该以 / 结尾。

        我只是在这里猜测.../admin/ 目录不是您的模板根目录。如果你还想写绝对路径,你应该去掉对管理模板目录的引用。

        TEMPLATE_DIRS = [
            'C:/django-project/myapp/mytemplates/',
        ]
        

        话虽如此,默认情况下模板加载器应设置为递归遍历您的应用目录以定位模板文件。

        TEMPLATE_LOADERS = [
            'django.template.loaders.filesystem.load_template_source',
            'django.template.loaders.app_directories.load_template_source',
            # 'django.template.loaders.eggs.load_template_source',
        ]
        

        除非您特别想覆盖某些内容,否则您不需要复制管理模板。

        如果您还没有运行同步数据库,则必须运行它。如果您通过 runserver 托管 django,您还需要静态地为您的媒体文件提供服务。

        【讨论】:

        • 非常感谢删除 TEMPLATE_DIRS 相对路径末尾的“/admin”。
        • 此建议将模板目录放在项目文件夹中。为了更好地组织,将其放在应用程序的文件夹中是否更有意义?
        • 这解决了我的问题。谢谢。但是,默认设置文件有一条带有 TEMPLATE_DIRS 的注释,“不要忘记使用绝对路径,而不是相对路径。”有人知道该评论的理由吗?
        • PROJECT_PATH 是项目文件夹的绝对路径。此方法在运行时动态设置绝对媒体路径,因此该值不是硬编码的,并且可以随着项目的位置自动更改。这是一篇旧文章,但您可以使用它来定义项目中任何文件夹或文件的位置。
        • 我建议使用os.path.join 将路径附加到基本目录。
        【解决方案5】:

        在 django 3.1 中,进入项目设置并导入操作系统

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

        【讨论】:

          【解决方案6】:

          基本上BASE_DIR 是您的django 项目目录,与manage.py 所在的目录相同。

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

          【讨论】:

            【解决方案7】:

            好吧?假设你有一个全新的项目,如果是这样,你会去settings.py文件并搜索TEMPLATES一旦你找到它你只需将这行os.path.join(BASE_DIR, 'template')粘贴到'DIRS'最后,你应该得到这样的东西:

            TEMPLATES = [
                {
                    'BACKEND': 'django.template.backends.django.DjangoTemplates',
                    'DIRS': [
                        os.path.join(BASE_DIR, 'template')
                    ],
                    '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',
                        ],
                    },
                },
            ]
            

            如果您想知道 BASE_DIR 目录的位置,请输入以下 3 个简单命令:

            python3 manage.py shell
            

            一旦你进入了外壳:

            >>> from django.conf import settings
            >>> settings.BASE_DIR
            

            PS:如果你用另一个名字命名你的模板文件夹,你也会在这里改变它。

            【讨论】:

              【解决方案8】:

              在 django 2.2 中对此进行了解释

              https://docs.djangoproject.com/en/2.2/howto/overriding-templates/

              import os
              
              BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
              
              INSTALLED_APPS = [
                  ...,
                  'blog',
                  ...,
              ]
              
              TEMPLATES = [
                  {
                      'BACKEND': 'django.template.backends.django.DjangoTemplates',
                      'DIRS': [os.path.join(BASE_DIR, 'templates')],
                      'APP_DIRS': True,
                      ...
                  },
              ]
              

              【讨论】:

                【解决方案9】:

                Django 2.0.3 中用于将模板保存在项目目录中的智能解决方案 (/root/templates/app_name):

                settings.py

                BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
                TEMP_DIR = os.path.join(BASE_DIR, 'templates')
                ...
                TEMPLATES = [
                {
                    'BACKEND': 'django.template.backends.django.DjangoTemplates',
                    'DIRS': [TEMP_DIR],
                ...
                

                在views.py中添加这样的模板路径:

                app_name/html_name
                

                【讨论】:

                  【解决方案10】:

                  对于 Django 1.6.6:

                  BASE_DIR = os.path.dirname(os.path.dirname(__file__))
                  TEMPLATE_DIRS = os.path.join(BASE_DIR, 'templates')
                  

                  还有用于调试和生产模式的静态和媒体:

                  STATIC_URL = '/static/'
                  MEDIA_URL = '/media/'
                  if DEBUG:
                      STATIC_ROOT = os.path.join(BASE_DIR, 'static')
                      MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
                  else:
                      STATIC_ROOT = %REAL_PATH_TO_PRODUCTION_STATIC_FOLDER%
                      MEDIA_ROOT = %REAL_PATH_TO_PRODUCTION_MEDIA_FOLDER%
                  

                  必须在 urls.py 中添加:

                  from django.conf.urls import patterns, include, url
                  from django.contrib import admin
                  from django.conf.urls.static import static
                  from django.conf import settings
                  
                  from news.views import Index
                  
                  admin.autodiscover()
                  
                  urlpatterns = patterns('',
                      url(r'^admin/', include(admin.site.urls)),
                      ...
                      )
                  
                  urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
                  

                  在 Django 1.8 中,您可以在一个字典中为模板设置模板路径、后端和其他参数(settings.py):

                  TEMPLATES = [
                      {
                          'BACKEND': 'django.template.backends.django.DjangoTemplates',
                          'DIRS': [
                              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',
                              ],
                          },
                      },
                  ]
                  

                  Official docs.

                  【讨论】:

                  • 模板路径需要是一个元组:使用这个 TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
                  【解决方案11】:

                  如果使用已安装的 Django 设置,那么为什么不直接使用其内置的、预定义的 BASE_DIR 和 TEMPLATES?在 pip 安装的 Django(v1.8) 中,我得到:

                  BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
                  
                  
                  TEMPLATES = [
                      {
                          'BACKEND': 'django.template.backends.django.DjangoTemplates',
                          'DIRS': [
                              ### ADD YOUR DIRECTORY HERE LIKE SO:
                              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',
                              ],
                          },
                      },
                  ]
                  

                  【讨论】:

                  • 这个 «BASE_DIR + '/templates/'," 成功了。而且它看起来更优雅,而不是单独的部分。
                  • 使用os.path.join(BASE_DIR, 'templates') 使路径独立于平台。
                  【解决方案12】:

                  本教程的这一部分也有问题(使用 1.7 版的教程)。

                  我的错误是我只编辑了“Django 管理”字符串,并没有对手册给予足够的重视。

                  这是来自 django/contrib/admin/templates/admin/base_site.html 的行:

                  <h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
                  

                  但经过一段时间和挫折后,很明显有 'site_header or default:_' 声明,应该删除。因此,在删除该语句后(如手册中的示例,一切都按预期工作)。

                  示例手册:

                  <h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
                  

                  【讨论】:

                    猜你喜欢
                    • 2021-07-21
                    • 2014-09-15
                    • 2018-04-16
                    • 2011-08-14
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多