I have a django template which is used from many views. The template has a block for messages used to notify user of anything that should take their attention. Whether a message is sent or not depends on the views. Some views may send a message
variable to the template while others may not.
view_1:
message = "This is an important message"
render_to_response("my_template.html",
{'message':message, 'foo':foo, 'bar':bar},
context_instance = RequestContext(request))
view_2:
message = "This is an important message"
render_to_response("my_template.html",
{'foo':foo, 'bar':bar},
context_instance = RequestContext(request))
In the template, I check for the message
variable and include the block as below:
base_template.html:
....
{% block main_body %}
{% block messages %}
{% endblock %}
{% block content %}
{% endblock %}
{% endblock %}
....
my_template.html:
{% extends base_template.html %}
....
{% if message %}
{% block messages %}
<div class='imp_msg'>{{ message }} </div>
{% endblock %}
{% endif %}
...
Problem is that even if view_2 does not pass a message, the final html is rendered with <div class='imp_msg'></div>
-- basically an empty div.
Since that CSS is designed to give a light_red background to messages, what I see is an empty light_red bar on the top of the page.
I also tried: {% ifnotequal message None %}
, {% ifnotequal message '' %}
, tried setting the message
to None
or ''
explicitly, but does not seem to help.
Would appreciate some help!
You need to switch your {% block %}
and your {% if %}
{% block messages %}
{% if message %}<div class='imp_message'>{{ message }}</div>{% endif %}
{% endblock %}
To check, in an if statement, you need to compare the value to None
, like this:
{% if some_missing_var is None %}
// code here if some_missing_var exists
{% else %}
// code here if some_missing_var does not exist
{% endif %}
In other cases (from the docs):
Generally, if a variable doesn’t exist, the template system inserts the value of the engine’s string_if_invalid configuration option, which is set to '' (the empty string) by default.
I tried some of the other answers, and they didn't work until I read the docs on how invalid variables are handled and the above was made clear.
link to docs that describe handling invalid variables
{% if result %}
even if result
was defined but empty. I wanted it to pass when result
was defined and fail when result was not defined. For empty result
, I wanted to display another message. Checking for None
worked great.
If you don't want to litter your logs with KeyError
when there is no variable in the template context I recommend to use templatetags filters.
In myapp/templatetags/filters.py
I add:
@register.simple_tag(takes_context=True)
def var_exists(context, name):
dicts = context.dicts # array of dicts
if dicts:
for d in dicts:
if name in d:
return True
return False
In html template:
{% load filters %}
...
{% var_exists 'project' as project_exists %}
{% if project_exists %}
...
{% endif}
{% block messages %}
in your base template, and the django template rendering engine takes that and looks for, and injects, that block wherever it's extended, and ignores anyif
s or anything else around it. That being said, I can't swear to you that an{% if %}
around a{% block %}
would ever work-- I've never tried it, so I don't know either way. It could be that it never works, and that's the primary problem, not that you have{% block messages %}
in your base.{% if %}
were in base, then, it would work. Or if the block was not in base.{% if messages != None %}