【问题标题】:How to override template in django-allauth?如何覆盖 django-allauth 中的模板?
【发布时间】:2013-09-18 10:13:21
【问题描述】:

其他问题的答案给人的印象是这实际上很容易:

但是,我根本无法让它工作。

example app settings 我可以看到django-allauth 预计它的模板在accountopenidsocialaccount 目录中。但是当我将模板放在TEMPLATE_DIR/account/signup.html 时,它不会被加载,signup 视图会显示与 django-allauth 捆绑在一起的模板。我错过了什么?

【问题讨论】:

    标签: python django django-allauth


    【解决方案1】:

    我最终求助于在 django-allauth 之前加载我的应用程序。在settings.py:

    INSTALLED_APPS = (
        ...
        'myapp',
        'allauth',
        'allauth.account'
    )
    

    此解决方案与示例应用程序中的内容背道而驰,但我无法以其他方式解决它。

    【讨论】:

    • 它有效,但正如你所说,这似乎不是最好的方法。我认为 allauth 在设置中应该有一个 config var 来指定所有模板的路径。
    • 谢谢你 - 正如你所说的@miguelfg 它有效 - 但它似乎根本不对。你们有没有找到更好的方法?
    • @awidgery in allauth 0.18 模板覆盖适用于我,无论应用程序加载优先级如何。我只是将模板放在正确的目录中,然后在默认目录之前加载它们。
    • 这仍然是唯一对我有用的解决方案,使用 Django 1.11.5 和 django-allauth 0.33.0。 @Red 是对的——文档中没有提到。
    【解决方案2】:

    直到今天——我们现在使用的是 Django-1.10.5——django-allauth 文档在这方面仍然毫无帮助。似乎 Django 在列出的第一个应用程序的模板目录中查找,尽管 TEMPLATES 中的 DIRS 设置在 settings.py 中。我提供一个答案只是为了帮助您实施 Adam Starrh 的答案,以帮助处理反向 url(在我处理这些错误之前我遇到了错误)。

    在你的 urls.py 文件中放:

    from allauth.account.views import SignupView, LoginView, PasswordResetView
    
    class MySignupView(SignupView):
        template_name = 'signup.html'
    
    class MyLoginView(LoginView):
        template_name = 'login.html'
    
    class MyPasswordResetView(PasswordResetView):
        template_name = 'password_reset.html'
    
    urlpatterns = [
        url(r'^accounts/login', MyLoginView.as_view(), name='account_login'),
        url(r'^accounts/signup', MySignupView.as_view(), name='account_signup'),
        url(r'^accounts/password_reset', MyPasswordResetView.as_view(), name='account_reset_password'),
    ]
    

    目前views.py文件是here,所以你可以将上面的内容扩展到其他模板。

    我必须补充一点,您仍然需要TEMPLATES,例如:

    'DIRS': [
        os.path.join(PROJECT_ROOT, 'templates', 'bootstrap', 'allauth', 'account'),
    ],
    

    在此示例中,如果您的模板位于/templates/bootstrap/allauth/account 中,在我的情况下就是这样。并且:

    PROJECT_ROOT = os.path.normpath(os.path.dirname(os.path.abspath(__file__)))
    

    编辑...正确的方法:

    好的,上面的工作,在一定程度上,它直接将模板设置为你想要的很好。但是,一旦您包含社交应用程序,您就会开始收到反向 url 错误,例如 dropbox_login,您尚未为其提供命名视图。

    在阅读了提问者发现的Burhan Khalid对this other stackoverflow thread的评论后,我最终发现以下工作:

    'DIRS': [
        os.path.join(PROJECT_ROOT, 'templates', 'example'),
    ]
    

    在我的情况下,这会在开发服务器上产生/home/mike/example/example/templates/example,因为我正在从git clone git://github.com/pennersr/django-allauth.git 运行example 应用程序。

    DIRS 的目录中,我从提供的示例bootstrap 模板中复制了整个子目录accountsocialaccount。这与example 的目录结构完全相反,因为它来自githubexamplesettings.py 文件中的注释。

    然后您离开urls.py,就像在example 应用程序中一样,只需:

        url(r'^accounts/', include('allauth.urls')),  
    

    【讨论】:

      【解决方案3】:

      Adding a template directory for allauth in template dirs 可以解决问题。在 Django 1.8 中,他可以通过编辑模板目录 settingsTEMPLATES 来完成,如下所示。

      TEMPLATES = [
          ...
          'DIRS': [
              os.path.join(BASE_DIR, 'templates'),
              os.path.join(BASE_DIR, 'templates', 'allauth'),
          ],
      ]
      

      我认为下面的代码适用于其他版本的 django

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

      【讨论】:

      • 一个小修正。我也在尝试相同的方法,并且没有命中自定义 allauth 模板。原因是我的模板在rootDir/templates/allauth/templates。因此需要进行两项更改。 (1) - 将APP_DIRS : True 添加到模板TEMPLATE_DIRS, (2) - 将account/ 复制到allauth 文件夹或使用os.path.join(BASE_DIR,'templates', 'allauth', 'templates')
      【解决方案4】:

      在你看来:

      from allauth.account.views import SignupView, LoginView
      
      
      class MySignupView(SignupView):
          template_name = 'my_signup.html'
      
      
      class MyLoginView(LoginView):
          template_name = 'my_login.html'
      

      【讨论】:

        【解决方案5】:

        根据here 提供的文档,可以通过复制项目模板基位置内的目录结构来覆盖模板。例如,通过创建 account/logout.html ,我能够覆盖 allauth 提供的 logout.html 文件。在我的情况下,settings.py 在这里说明

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

        【讨论】:

        • 是的,这是为我做的。文件的模板/帐户/logout.html。
        • 忘了说..在 Django 3.1.4 上。
        • 非常感谢!帐户/部分为我做了。
        【解决方案6】:

        对我来说只有一种解决方案有效:

        首先使 TEMPLATE_LOADERS 加载 filesystem.Loader

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

        second - 使用从 allauth 复制模板的路径创建 TEMPLATE_DIRS。确保您从 allauth 应用程序的模板文件夹中复制了完整的文件夹层次结构。

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

        在这个例子中,我的应用程序的路径被命名为 cms,因为这是我项目的主要应用程序 在你可以开始编辑 base.html 模板之后

        【讨论】:

          【解决方案7】:

          我找到了更好的方法,但忘记了。 All Auth 允许您非常容易地做到这一点,但文档很少。这是我的下一个最简单的解决方案,直到我重新发现更广泛的方法。 #大声笑

          该代码创建了一个自定义登录页面,但该模式简单且易于复制。您可以将所有这些代码放在urls.py 中,也可以不:

          from allauth.account.views import LoginView
          
          
          class Lvx(LoginView):
              # Login View eXtended
          
              # beware ordering and collisions on paths
              template_name = "components/login.html"
          
              # don't forget to create the login page, see All Auth docs
              # for use. /components is in your app templates path
          
          
          login = Lvx.as_view()
          
          urlpatterns = [
              url(r'^accounts/login/$', login),  # usually up top
              ...
          ]
          

          还有一个设置可以用来指向一个自定义页面,在某个时候会对其进行编辑。欢迎反馈。

          【讨论】:

            【解决方案8】:

            在 django v2.0 中。我使用这种方法及其作品。通过遵循 django 书籍,[https://djangobook.com/mdj2-django-templates/]

            重要的方式是使用[os.path.join(BASE_DIR, 'name_of_your_file/templates/allauth')]而不是使用'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates', 'allauth')],

            TEMPLATES = [
                {
                    'BACKEND': 'django.template.backends.django.DjangoTemplates',
                    'DIRS': [os.path.join(BASE_DIR, 'name_of_your_file/templates/allauth')],
                    'APP_DIRS': True,
            

            这是我第一次在stackoverflow上发帖,我发现这个解决方案很久了,终于成功了,所以我分享它,希望可以帮助别人。

            【讨论】:

              【解决方案9】:

              一旦您了解了 Django 的 模板查找顺序 并根据需要正确配置 TEMPLATE =[],这将非常容易。如果只是覆盖 allauth 的模板,则无需使用视图或 Python 代码。

              我们先来了解一下Django的模板查找顺序,一点点。 Django的模板查找顺序如下,所有这些都在项目的settings.py中TEMPLATE =[]里面配置。

              我。 'Loader':让您可以选择使用负责定位模板、加载模板和返回模板对象的模板加载器。一般实现不会使用它。如果您尚未配置模板加载器,则以下两个选项之一将决定您的视图使用哪个模板。

              二。 'DIRS':在这里你可以选择明确地告诉 Django 在哪里搜索模板,按顺序,从上到下。

              三。 'APP_DIRS':如果此字段设置为 true,则 Django 会在您的应用程序目录中查找您的模板。要正确使用此选项,您需要按如下方式组织模板:

              root_dir
               app1_dir
                templates
                 your_template.html
               app2_dir
                templates
                 your_template.html
              

              您必须将您的模板目录命名为 "templates",并且您必须将模板放在该目录中才能正常工作

              不过,第三个选项有点奇怪,如果在相应应用的模板目录中找不到您应用视图中的模板,Django 将通过其他应用的模板目录找到它。 如果模板组织得当并且模板的命名约定是标准化的,那么它会很好地工作,这样当在本地应用程序的目录中找不到模板时,不应该在其他应用程序的目录中错误地找到该模板。好吧,您可能在某些情况下希望它以这种方式工作。

              现在,直接回答您的问题: Allauth 默认使用以下模板:

              Python installed directory or virtual env --> *Lib --> site-packages --> allauth --> templates*
              

              您通常希望覆盖所有 allauth 的模板,因为它们非常基本,并且您希望全部美化/修改它们,如果您不想覆盖,以下是使您能够覆盖它们的步骤它们都按如下方式进行,但只是不要更改该模板的 HTML,简单!

              假设你的项目结构如下:

              projectdir
                app1_dir
                app2_dir
                projectname_dir
              

              将模板目录从Python installed directory or virtual env --> Lib --> site-packages --> allauth --> templates复制到您选择的目录,假设您选择将其保存在app1_dir中(您可以选择任何目录,没有区别,但您应该根据您的要求选择一个合适的目录),然后在 app1_dir 中创建一个名为 'allauth' 的目录(您可以将其命名为任何您喜欢的名称),然后将复制的 allauth 的模板目录粘贴到此目录中,所以现在您的项目结构如下所示:

              projectdir
                app1_dir
                  allauth
                    templates
                      account
                      openid
                      socialaccount
                      base.html
                app2_dir
                projectname_dir
              

              在项目设置中更改您的TEMPLATES = [],如下所示:

              TEMPLATES = [
                  {
                      'BACKEND': 'django.template.backends.django.DjangoTemplates',
                      'DIRS': [os.path.join(BASE_DIR, 'allauth', 'templates'),
              
                              ],
                      'APP_DIRS': True,
                  },
              ]
              

              这里 BASE_DIR 是 projectdir(根目录)

              基本上,您可以将 allauth 目录中复制的模板目录保存在您选择的任何项目目录中,但您必须确保您在此处提供了正确的路径:

              'DIRS': [os.path.join(BASE_DIR, 'allauth', 'templates')
              

              如果它不起作用,请设置'APP_DIRS': False,然后您会看到来自 Django 的调试消息,并且它不会使用应用程序目录(站点包中的 allauth 目录)。然后查看该错误,您可能会发现您的配置有什么问题。

              【讨论】:

              • 谢谢你,你的解释非常好。
              猜你喜欢
              • 2019-07-11
              • 2014-08-30
              • 2012-03-15
              • 2019-01-12
              • 2016-06-04
              • 2014-06-08
              • 2019-08-01
              • 2019-08-11
              • 2016-09-16
              相关资源
              最近更新 更多