#Help TemplateDoesNotExist

9 messages · Page 1 of 1 (latest)

fathom schooner
#

I have a widgets.py file in the utils folder.

class CustomClearableFileInput(ClearableFileInput):
    clear_checkbox_label = _("Delete")
    template_name = "components/widgets/clearable_file_input.html" 

And the file storage structure in my main templates looks like this.

.
└── templates
    └── components
        └── widgets
            └── clearable_file_input.html

But when I run it I get Error:

" TemplateDoesNotExist at components/widgets/clearable_file_input.html"

I have set "DIRS": [Path.joinpath(BASE_DIR, "templates")], in my project.

But if I put clearable_file_input.html in the templates of one of my apps and set template_name to that app it works.

But I want to have that clearable_file_input.html in the main templates, how do I do that? Is there a way?

#

I'm not good at English. I hope you understand.

modest pewter
#

did you delete report one?

fathom schooner
heady topaz
#

Instead of setting template_name as a class attribute, could you set it dynamically? Something like this.

class CustomClearableFileInput(ClearableFileInput):
    clear_checkbox_label = _("Delete")
    
    @property
    def template_name(self):
        # This is evaluated at render time, not import time
        return "components/widgets/clearable_file_input.html"
fathom schooner
fathom schooner
heady topaz
#

Great!

Django uses two main template loaders by default:

# This is what Django does internally (simplified)
template_loaders = [
    AppDirectoriesLoader(),    # Looks in each app's 'templates' folder
    FilesystemLoader(),         # Looks in your DIRS setting
]

Also, this is simple process, when django starts up.

# When Django starts up:
# 1. Settings are loaded
# 2. Apps are loaded (including their models and forms)
# 3. During app loading, your widgets.py might be imported
# 4. Every app loaded
# 5. Django template system is initialized.
# 6. DIRS path registration in TEMPLATES settings complete

AppDirectoriesLoader automatically registers the templates/ folder for each app as it loads. The FilesystemLoader, on the other hand, needs to read the DIRS setting in settings.TEMPLATES, which is fully initialized after all apps are loaded.

So, your class in widgets.py is imported too early, so that settings.TEMPLATES isn't initialized yet. That caused the error.

#

As you know I changed template_name as property. By using Python's @property decorator, we've transformed template_name from a simple attribute into a method that gets called whenever someone tries to access it.
The key difference is timing: this method won't be called until your widget actually needs to render, which happens long after Django has fully initialized.

P.S
Using @property in this case might cause negligible overhead. So, you can also try this one.

class CustomClearableFileInput(ClearableFileInput):
    clear_checkbox_label = _("Delete")
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.template_name = "components/widgets/clearable_file_input.html"