Capturing DoesNotExist template in Django

I am trying to use the templatetag described in the SO answer: https://stackoverflow.com/a/166508/ in a project using Django 1.4.3 (with Python 2.7.2).

I adapted it like this:

from django import template register = template.Library() @register.filter def template_exists(template_name): try: template.loader.get_template(template_name) return True except template.TemplateDoesNotExist: return False 

So that I can use it in the following template:

 {% if 'profile/header.html'|template_exists %} {% include 'profile/header.html' %} {% else %} {% include 'common/header.html' %} {% endif %} 

That way, I could avoid using solutions like changing the order of my applications in INSTALLED_APPS.

However, this will not work. If the template does not exist , then an exception is thrown inside the stack / console, but it does not propagate to get_template(..) (from the inside ) and therefore not for my silly API. Consequently, it explodes on my face during rendering. I loaded stacktrace in pastebin

Is this the right behavior from Django?

I stopped doing stupid things as they are. But my question would remain.

+4
source share
2 answers

How about a custom tag? This does not provide the full functionality of include , but seems to meet the needs of this question .:

 @register.simple_tag(takes_context=True) def include_fallback(context, *template_choices): t = django.template.loader.select_template(template_choices) return t.render(context) 

Then in your template:

 {% include_fallback "profile/header.html" "common/header.html" %} 
+2
source

I found some answer to my question, so I post it here for future confirmation.

If I use a filter template_exists like this

 {% if 'profile/header.html'|template_exists %} {% include 'profile/header.html' %} {% else %} {% include 'common/header.html' %} {% endif %} 

and if profile/header.html does not exist, then TemplateDoesNotExist gets a strange distribution when the page loads, and I get a server error. However, if instead I use this in my template:

 {% with 'profile/header.html' as var_templ %} {% if var_templ|template_exists %} {% include var_templ %} {% else %} {% include 'common/header.html' %} {% endif %} {% endwith %} 

Then it works like a charm!

Obviously i could use

 django.template.loader.select_template(['profile/header.html','common/header.html']) 

in view (from this SO answer ). But I use CBV, which I would like to keep fairly universal, and this was called from the main template. And also I thought that it would be nice if my site worked, if for some reason these applications are down. If this seems silly to you, please leave a comment (or an even better answer).

0
source

All Articles