Home > OS >  Django template's include not sharing static files
Django template's include not sharing static files

Time:10-22

I have a large Django project with multiple templates which are merged later on to construct pages dynamically, I am facing a weird issue as follows:

  1. I have a base.html which includes all the needed imports, including JS and CSS.

  2. I have sub-folders for both CSS/JS in the assets, which are usually imported at the end of base.html.

Now, as my project got bigger, I decided I'd rather have the scripts imports, e.g:

<script type="text/javascript" src="{% static "js/base.js" %}"></script>
<script type="text/javascript" src="{% static "js/menus/projects.js" %}"></script>
<script type="text/javascript" src="{% static "js/menus/sensors.js" %}"></script>

included in each individual HTML file, instead of all being in the base.html, I expected to have no issues, since as far as I know include statements should also transfer context, for reference sake, those are the include statements of interest:

  • in base.html:
{% include "applications/Devices/deviceDashboard.html" %}
  • in deviceDashboard.html:
{% include "applications/Devices/deviceDashboard/listCard.html" %}
{% include "applications/Devices/deviceDashboard/editCard.html" %}
{% include "applications/Devices/deviceDashboard/graphCard.html" %}

In all of those, if I try to run it as-is I get the following:

TemplateSyntaxError at /

Invalid block tag on line 25: 'static'. Did you forget to register or load this tag?

When I try to use the same script import tags as before, and this issue is gone when I use {% load static %} for each individual page. I have {% load static %} in my base.html, but it only applies in that file, and not to any of the sub-files called through the include function.

Why doesn't the include copy the context here? Or does it not copy "static" by default? I suspect this should be a simple misunderstanding from my part about how include is supposed to work here, but I wasn't able to find anything while searching. Finally, if its how import works, how can I resolve this issue?

CodePudding user response:

Django's load template tag only loads packages for the specific template file, and are not inherited through extends or include tags.

See for an explanation this bug report:

My understanding is that this is a feature, not a bug. The template system only provides the tags loaded in each template file itself so that templates can be reused without having to guess at what their environment expectations are.

A fix for the problem of having to put {% load i18n %} in every template might be to add an app-specific automatically loaded template setting, so each app author can decide what the base namespace for their templates is. This would require adding an app-specific configuration system, and somehow letting the template module know what the 'current app' is.

If you want specific tags to be available in all templates, you can use the approach used here: Load static files for all templates in django

CodePudding user response:

Define static files settings in django project settings.py

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "static/")

MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"

Also add this to your project main urls.py

urlpatterns  = static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns  = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  • Related