Opened 10 years ago
Closed 10 years ago
#24891 closed New feature (wontfix)
Warn if referencing a template by the same name as one in an installed app with higher precedence
Reported by: | Markus Amalthea Magnuson | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Due to how precedence works when looking up templates, you can write an app that e.g. in one of its views references a template name in the same app, but that will never actually be used if one by the same name exists in another app that is listed earlier in INSTALLED_APPS
.
This can be quite a surprise and frustration if you are not aware of it, trying to debug why your template is not being used. The common solution is to have an additional subdirectory in the app template folder, named like the app itself. But you will have to find that out first, somehow.
I'd suggest some kind of warning is emitted if an installed app is referencing a template name that also exists in another installed app with higher precedence. The warning would ideally only happen if that template actually exists in the app with lower precedence.
What do you think?
Change History (4)
comment:1 by , 10 years ago
follow-up: 3 comment:2 by , 10 years ago
I understand the confusion here, but the warning behavior is a little ambiguous. What if multiple loaders are defined? Or what if recursive inheritance is used? It's valid for an application to extend a template from another application with the same name.
Some better solutions may be to:
1) Add logging in django.template.loader
for template.origin.name
so the full template paths can be logged to the console.
2) Use Django debug toolbar to see which template was used.
comment:3 by , 10 years ago
Replying to prestontimmons:
I understand the confusion here, but the warning behavior is a little ambiguous. What if multiple loaders are defined? Or what if recursive inheritance is used? It's valid for an application to extend a template from another application with the same name.
Some better solutions may be to:
1) Add logging in
django.template.loader
fortemplate.origin.name
so the full template paths can be logged to the console.
2) Use Django debug toolbar to see which template was used.
I guess in the case of multiple loaders the check could be per loader or something like that. No warning would be emitted in the case of templates extending each other. However, of course this entire idea would need more work to handle various complex template scenarios. It might turn out to actually be an improvement to the documentation or such. But I've seen over and over developers rather new to Django run into this and I think there could be some improvement.
Basically, you can have a template in your app and reference it, without there ever being a possibility of that template being used, unless you have read a specific sentence in the documentation or otherwise know why. Logging and debugging of course help to figure this out, but I think we could make it even easier (and time efficient) by pointing it out to begin with, since we can probably know the occurrence of this case from just known facts about the current project/settings.
comment:4 by , 10 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
There's a big warning about this in the first mention of template names in the tutorial, recommending the use of a subfolder - https://docs.djangoproject.com/en/dev/intro/tutorial03/#a-shortcut-render
This is further explained, along with the way multiple backends are resolved in the API docs.
Adding such a warning would require additional work every time a template is selected - and would be specific to one template engine. It would generate unnecessary noise in the common, documented in the tutorial pattern of overriding an admin template with one in your own app.
+1 to using debug toolbar.
I don't see an obvious opportunity for more documentation as they way it works is mentioned several times in the API docs and twice in the tutorial. Adding warnings would generate unnecessary noise. Template overriding is an important feature. Consequently, I am closing this ticket.
I'm not sure it's feasible to implement. A template loading call would have to know the "current app" from where it's being called. Is there a clean way to get that information?