为什么 Django 模板加载器在生产中区分大小写但在开发中不区分大小写
Why Django template loader is case-sensitive in production but not in development
我在 MacOs Catalina OS 上使用 manage.py runserver
作为开发。我有一些模板适合我基于 class 的内置视图。例如:
CuadroDeControl_detail.html LoteDeMedio_list.html TipoDeMedio_detail_tablaCuadros.html
CuadroDeControl_detail_resumen.html LoteDeMedio_list_tabla.html TipoDeMedio_list.html
CuadroDeControl_detail_tablaMetodos.html MetodoDeControl_detail.html TipoDeMedio_list_tabla.html
LoteDeMedio_confirm_delete.html MetodoDeControl_detail_resumen.html dropdown_CuadroDeControl.html
LoteDeMedio_create.html TipoDeMedio_confirm_delete.html dropwdown_CuadroDeControl.html
LoteDeMedio_detail.html TipoDeMedio_detail.html
LoteDeMedio_detail_resumen.html TipoDeMedio_detail_resumen.html
这是工作视图的示例:
class TipoDeMedioDetailView(AreaCalidadMixin, DashboardMixin, DetailView):
model = TipoDeMedio
请注意,我的观点并未明确设置 template_name
。在我的制作中
环境,我所有的观点都加载得很好。 Django的模板加载器知道视图对应的模板是TipoDeMedio_detail.html
但是,在我的生产环境中,在 Ubuntu 20.04.2 LTS x86_64 Linode VM 上设置了 apache2
和 mod_wsgi
,模板加载器无法加载同一视图的模板,因为它以全小写形式搜索它。这是一个例子:
Request Method: GET
Request URL: http://45.79.4.38/calidad/TipoDeMedio/lista
Django Version: 3.1.6
Exception Type: TemplateDoesNotExist
Exception Value:
calidad/tipodemedio_list.html
Exception Location: /home/jonatan/django-app/venv/lib/python3.8/site-packages/django/template/loader.py, line 47, in select_template
Python Executable: /home/jonatan/django-app/venv/bin/python
Python Version: 3.8.5
Python Path:
['/home/jonatan/django-app/mysite',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/home/jonatan/django-app/venv/lib/python3.8/site-packages']
Server time: Mon, 21 Jun 2021 18:24:19 -0500
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.filesystem.Loader: /home/jonatan/django-app/mysite/templates/calidad/tipodemedio_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/jonatan/django-app/mysite/login/templates/calidad/tipodemedio_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/jonatan/django-app/venv/lib/python3.8/site-packages/django/contrib/admin/templates/calidad/tipodemedio_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/jonatan/django-app/venv/lib/python3.8/site-packages/django/contrib/auth/templates/calidad/tipodemedio_list.html (Source does not exist)
一个简单的解决方法是在我的每个 CBV
上手动指定我的 template_name
属性并指向正确的区分大小写的模板名称(例如 TipoDeMedio_detail.html
。但是,我真的很想避免这种情况。
我只是想了解环境之间行为变化的根本原因是什么。它只是让我相信我会在 Django 行为的其他方面遇到类似的问题。
默认的 Apple 文件系统 (APFS) 不区分大小写。这意味着在 Mac 的开发过程中,即使文件名使用了不正确的大小写,Django 也能够找到模板。
现在您已经移动到 Ubuntu,它默认使用区分大小写的文件系统。如果大小写错误,Django 将无法找到模板。
请注意 Django docs for class-based generic views 状态:
... in the absence of an explicit template Django will infer one from the object’s name ... is the lowercased version of the model’s name.
更好的解决方案是使用小写重命名模板。
MattRowbum 向我指出 APFS 不区分大小写。我认为这足以解释行为的变化。
我在 MacOs Catalina OS 上使用 manage.py runserver
作为开发。我有一些模板适合我基于 class 的内置视图。例如:
CuadroDeControl_detail.html LoteDeMedio_list.html TipoDeMedio_detail_tablaCuadros.html
CuadroDeControl_detail_resumen.html LoteDeMedio_list_tabla.html TipoDeMedio_list.html
CuadroDeControl_detail_tablaMetodos.html MetodoDeControl_detail.html TipoDeMedio_list_tabla.html
LoteDeMedio_confirm_delete.html MetodoDeControl_detail_resumen.html dropdown_CuadroDeControl.html
LoteDeMedio_create.html TipoDeMedio_confirm_delete.html dropwdown_CuadroDeControl.html
LoteDeMedio_detail.html TipoDeMedio_detail.html
LoteDeMedio_detail_resumen.html TipoDeMedio_detail_resumen.html
这是工作视图的示例:
class TipoDeMedioDetailView(AreaCalidadMixin, DashboardMixin, DetailView):
model = TipoDeMedio
请注意,我的观点并未明确设置 template_name
。在我的制作中
环境,我所有的观点都加载得很好。 Django的模板加载器知道视图对应的模板是TipoDeMedio_detail.html
但是,在我的生产环境中,在 Ubuntu 20.04.2 LTS x86_64 Linode VM 上设置了 apache2
和 mod_wsgi
,模板加载器无法加载同一视图的模板,因为它以全小写形式搜索它。这是一个例子:
Request Method: GET
Request URL: http://45.79.4.38/calidad/TipoDeMedio/lista
Django Version: 3.1.6
Exception Type: TemplateDoesNotExist
Exception Value:
calidad/tipodemedio_list.html
Exception Location: /home/jonatan/django-app/venv/lib/python3.8/site-packages/django/template/loader.py, line 47, in select_template
Python Executable: /home/jonatan/django-app/venv/bin/python
Python Version: 3.8.5
Python Path:
['/home/jonatan/django-app/mysite',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/home/jonatan/django-app/venv/lib/python3.8/site-packages']
Server time: Mon, 21 Jun 2021 18:24:19 -0500
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.filesystem.Loader: /home/jonatan/django-app/mysite/templates/calidad/tipodemedio_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/jonatan/django-app/mysite/login/templates/calidad/tipodemedio_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/jonatan/django-app/venv/lib/python3.8/site-packages/django/contrib/admin/templates/calidad/tipodemedio_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/jonatan/django-app/venv/lib/python3.8/site-packages/django/contrib/auth/templates/calidad/tipodemedio_list.html (Source does not exist)
一个简单的解决方法是在我的每个 CBV
上手动指定我的 template_name
属性并指向正确的区分大小写的模板名称(例如 TipoDeMedio_detail.html
。但是,我真的很想避免这种情况。
我只是想了解环境之间行为变化的根本原因是什么。它只是让我相信我会在 Django 行为的其他方面遇到类似的问题。
默认的 Apple 文件系统 (APFS) 不区分大小写。这意味着在 Mac 的开发过程中,即使文件名使用了不正确的大小写,Django 也能够找到模板。
现在您已经移动到 Ubuntu,它默认使用区分大小写的文件系统。如果大小写错误,Django 将无法找到模板。
请注意 Django docs for class-based generic views 状态:
... in the absence of an explicit template Django will infer one from the object’s name ... is the lowercased version of the model’s name.
更好的解决方案是使用小写重命名模板。
MattRowbum 向我指出 APFS 不区分大小写。我认为这足以解释行为的变化。