How to check if django template variable is defined?

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!


Solution 1:

You need to switch your {% block %} and your {% if %}

{% block messages %}
    {% if message %}<div class='imp_message'>{{ message }}</div>{% endif %}
{% endblock %}

Solution 2:

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

Solution 3:

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}