ChatGPT解决这个技术问题 Extra ChatGPT

如何检查是否定义了 django 模板变量?

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!


C
Colleen

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

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

Thanks @Colleen. That worked. Could you please explain though why the other way didn't? I just felt it was logical to include the block only if the message existed.
I think it's because you have {% 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 any ifs 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.
stackoverflow.com/questions/942797/… makes it sound as if it's the former. I think if your {% if %} were in base, then, it would work. Or if the block was not in base.
What about if 'message' were 0? Maybe you want to show the value 0, then you will have to use {% if messages != None %}
c
cgl

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


This worked great for me. In my use case, I was getting a list of results from a search and it was failing if I did {% 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.
I must be missing something, because on the face of it that if/else makes absolutely no sense! What if some_missing_var exists and is NOT None? I imagine that would generally be the case, because after all if a variable is present then the chances are the caller would have set it to something!
M
Max Tkachenko

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}

Exactly what I needed, works perfectly, thanks!

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅