Django returns TemplateDoesNotExist for namespaced app templates which are rendered by class views but works for plain function views

huangapple go评论80阅读模式
英文:

Django returns TemplateDoesNotExist for namespaced app templates which are rendered by class views but works for plain function views

问题

我是新手使用Django,并且有一个项目myproject,里面有一个名为users的应用程序。我无法弄清楚为什么在用户应用程序内的一个名为templates的文件夹中的子目录中对我的模板进行命名空间(所以路径是myproject/users/templates/users/)对于基于类的视图不起作用,但对于常规函数视图却可以正常工作。

当我使用基于类的视图时,我会收到错误消息Templateloader postmortem,其中显示:

django.template.loaders.app_directories.Loader: /home/me/projectmainfolder/myproject/users/templates/signup_form.html (Source does not exist)

django.template.loaders.app_directories.Loader: /home/me/projectmainfolder/penv/lib/python3.10/site-packages/django/contrib/admin/templates/signup_form.html (Source does not exist)

django.template.loaders.app_directories.Loader: /home/me/projectmainfolder/penv/lib/python3.10/site-packages/django/contrib/auth/templates/signup_form.html (Source does not exist)

当我将模板移到不带命名空间的子目录并放入templates时,它可以正常工作。

users/urls.py如下:

from django.urls import path, include
from . import views

app_name = "users"

urlpatterns = [
    path("accounts/", include("django.contrib.auth.urls")),
    # 可以正常工作
    path("accounts/test", views.testdef, name="test"),
    # 不能正常工作
    path("accounts/signup/user", views.UserSignupView.as_view(), name="signup_form"),
]

常规函数testdef如下:

def testdef(request):
    return render(request, "users/test.html")

类视图UserSignupView如下:

class UserSignupView(CreateView):
    model = CustomUser
    form_class = UserProfileSignupForm
    template_name = 'signup_form.html'

    def somefunction(self, **kwargs):
        ...

是否有任何解决方法将不胜感激。我希望根据Django的文档保持名称空间。我尝试移动文件并找到了成功的方法,但考虑到Django告诉您要以某种方式组织,这似乎不够理想。

英文:

I'm new to Django and have a project myproject and inside is an app, users. I can't figure out why name spacing the my templates in a subdirectory inside of a folder called templates within the users apps (so the path is myproject/users/templates/users/) does not work for class based views but it works fine for regular function views.

When using a class based view I get error message Templateloader postmortem saying:

django.template.loaders.app_directories.Loader: /home/me/projectmainfolder/myproject/users/templates/signup_form.html (Source does not exist)

django.template.loaders.app_directories.Loader: /home/me/projectmainfolder/penv/lib/python3.10/site-packages/django/contrib/admin/templates/signup_form.html (Source does not exist)

django.template.loaders.app_directories.Loader: /home/me/projectmainfolder/penv/lib/python3.10/site-packages/django/contrib/auth/templates/signup_form.html (Source does not exist)

When I move the template out of the name spaced sub-directory and into templates it works fine.

users/urls.py is:

from django.urls import path, include
from . import views

app_name = "users"

urlpatterns = [
    
    path("accounts/", include("django.contrib.auth.urls")),
    # works fine
    path("accounts/test", views.testdef, name="test"),
    #doesn't work
    path("accounts/signup/user", views.UserSignupView.as_view(), name="signup_form"),
]

The regular function testdef is :

def testdef(request):
    return render(request, "users/test.html")

The class view UserSignupView is:

class UserSignupView(CreateView):
    model = CustomUser
    form_class =UserProfileSignupForm
    template_name = 'signup_form.html'

    def somefunction(self, **kwargs):
        ...

Any idea how to resolve this is very appreciated. I would like to keep things name spaced according to Django's docs.

I tried moving the files around and found success that way but it seems sub-optimal considering Django tells you to organize a certain way.

答案1

得分: 1

Django在启用了**APP_DIRS**设置<sup>[Django文档]</sup>的情况下,在应用程序的templates/目录中进行搜索,并对所有应用程序都执行此操作。

这意味着您可以通过定义子目录来定义命名空间,然后在模板名称中使用它们。如果您的模板存储在<code>users/template/<b>users/signup_form.html</b></code>,您可以让Django查找以下模板:

<pre><code>class UserSignupView(CreateView):
model = CustomUser
form_class = UserProfileSignupForm
template_name = '<b>users/</b>signup_form.html'</code></pre>

对于基于函数的视图和基于类的视图,都是一样的。

模板加载程序在<code>render(&hellip;)</code>TemplateResponseMixin**<code>.render_to_response(&hellip;)</code>**方法<sup>[Django文档]</sup>之间在这个方面没有区别。

英文:

Django searches, if the APP_DIRS setting&nbsp;<sup>[Django-doc]</sup> is enabled, in the templates/ directories of the applications, and this for all applications.

This thus means that you can indeed define namespaces by just defining subdirectories, that you then use in the template names. If your template is thus stored at <code>users/template/<b>users/signup_form.html</b></code>, you let Django look for the template with:

<pre><code>class UserSignupView(CreateView):
model = CustomUser
form_class = UserProfileSignupForm
template_name = '<b>users/</b>signup_form.html'</code></pre>

this is the same for function-based views and class-based views.

The template loader is not different (at least not in that aspect) between <code>render(&hellip;)</code> and the <code>.render_to_response(&hellip;)</code> method&nbsp;<sup>[Django-doc]</sup> of the TemplateResponseMixin.

huangapple
  • 本文由 发表于 2023年6月26日 00:15:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定