How to chcek if a variable is "False" in Django templates?
Asked Answered
H

13

86

How do I check if a variable is False using Django template syntax?

{% if myvar == False %}

Doesn't seem to work.

Note that I very specifically want to check if it has the Python value False. This variable could be an empty array too, which is not what I want to check for.

Hairpiece answered 19/11, 2010 at 21:2 Comment(5)
Having a variable in the template context that can be both a list as well as a boolean seems like the wrong approach in the first place?Fleabite
@Fleabite I don't remember my use case. You could be right.Hairpiece
{% if not myvar%} it works in Django 1.11 for sure, I am not how far back you can go, though!Preinstruct
@Preinstruct Pretty sure not myvar checks if myvar is falsey, not False. see alsoHairpiece
@Hairpiece so if myvar was a boolean, not myvar will return True if it was sent to the template as a context variable by the render function regardless of its value (true or false)? in this case, one should check 2 things: 1-myvar was provided to the render function, 2-what value myvar has if provided. This will be pretty much complicated if myvar is more of a class instace, dictionary, object etc rather than a classic variable.Preinstruct
H
46

Django 1.10 (release notes) added the is and is not comparison operators to the if tag. This change makes identity testing in a template pretty straightforward.

In[2]: from django.template import Context, Template

In[3]: context = Context({"somevar": False, "zero": 0})

In[4]: compare_false = Template("{% if somevar is False %}is false{% endif %}")
In[5]: compare_false.render(context)
Out[5]: u'is false'

In[6]: compare_zero = Template("{% if zero is not False %}not false{% endif %}")
In[7]: compare_zero.render(context)
Out[7]: u'not false'

If You are using an older Django then as of version 1.5 (release notes) the template engine interprets True, False and None as the corresponding Python objects.

In[2]: from django.template import Context, Template

In[3]: context = Context({"is_true": True, "is_false": False, 
                          "is_none": None, "zero": 0})

In[4]: compare_true = Template("{% if is_true == True %}true{% endif %}")
In[5]: compare_true.render(context)
Out[5]: u'true'

In[6]: compare_false = Template("{% if is_false == False %}false{% endif %}")
In[7]: compare_false.render(context)
Out[7]: u'false'

In[8]: compare_none = Template("{% if is_none == None %}none{% endif %}")
In[9]: compare_none.render(context)
Out[9]: u'none'

Although it does not work the way one might expect.

In[10]: compare_zero = Template("{% if zero == False %}0 == False{% endif %}")
In[11]: compare_zero.render(context)
Out[11]: u'0 == False'
Helpmeet answered 5/5, 2015 at 15:23 Comment(3)
Will accept this so that it moves to the top and other people using current versions can find it :-)Hairpiece
I run in a problem when my context variable contains the integer 0 (zero). When it is rendered by django it is interpreted as 'False'. So it looks like i still need a custom template tag like Gabriel Hurley suggested.Riggle
Or You can explicitly check if variable is 0, but maybe template tag is less verbose.Helpmeet
P
52

For posterity, I have a few NullBooleanFields and here's what I do:

To check if it's True:

{% if variable %}True{% endif %}

To check if it's False (note this works because there's only 3 values -- True/False/None):

{% if variable != None %}False{% endif %}

To check if it's None:

{% if variable == None %}None{% endif %}

I'm not sure why, but I can't do variable == False, but I can do variable == None.

Petrillo answered 26/7, 2011 at 21:8 Comment(3)
A nicer idiom (recommended by PEP 8, comparisons to singletons like None should always be done with is or is not, never the equality operators) to check for Nones is using is, as None is a singletonKeg
@Beau: Django templates aren't Python code. These is no "is" operator in the template conditional expression.Pavier
This should be in a book somewhere. A lot of people use the models.NullBooleanField()Am
H
46

Django 1.10 (release notes) added the is and is not comparison operators to the if tag. This change makes identity testing in a template pretty straightforward.

In[2]: from django.template import Context, Template

In[3]: context = Context({"somevar": False, "zero": 0})

In[4]: compare_false = Template("{% if somevar is False %}is false{% endif %}")
In[5]: compare_false.render(context)
Out[5]: u'is false'

In[6]: compare_zero = Template("{% if zero is not False %}not false{% endif %}")
In[7]: compare_zero.render(context)
Out[7]: u'not false'

If You are using an older Django then as of version 1.5 (release notes) the template engine interprets True, False and None as the corresponding Python objects.

In[2]: from django.template import Context, Template

In[3]: context = Context({"is_true": True, "is_false": False, 
                          "is_none": None, "zero": 0})

In[4]: compare_true = Template("{% if is_true == True %}true{% endif %}")
In[5]: compare_true.render(context)
Out[5]: u'true'

In[6]: compare_false = Template("{% if is_false == False %}false{% endif %}")
In[7]: compare_false.render(context)
Out[7]: u'false'

In[8]: compare_none = Template("{% if is_none == None %}none{% endif %}")
In[9]: compare_none.render(context)
Out[9]: u'none'

Although it does not work the way one might expect.

In[10]: compare_zero = Template("{% if zero == False %}0 == False{% endif %}")
In[11]: compare_zero.render(context)
Out[11]: u'0 == False'
Helpmeet answered 5/5, 2015 at 15:23 Comment(3)
Will accept this so that it moves to the top and other people using current versions can find it :-)Hairpiece
I run in a problem when my context variable contains the integer 0 (zero). When it is rendered by django it is interpreted as 'False'. So it looks like i still need a custom template tag like Gabriel Hurley suggested.Riggle
Or You can explicitly check if variable is 0, but maybe template tag is less verbose.Helpmeet
P
44

I think this will work for you:

{% if not myvar %}
Patmos answered 25/11, 2011 at 12:52 Comment(1)
The question specifically mentioned checking for False values only and should not be triggered by empty arrays. This applies to both.Lachman
T
23

You could write a custom template filter to do this in a half-dozen lines of code:

from django.template import Library

register = Library()

@register.filter
def is_false(arg): 
    return arg is False

Then in your template:

{% if myvar|is_false %}...{% endif %}

Of course, you could make that template tag much more generic... but this suits your needs specifically ;-)

Turnstile answered 19/11, 2010 at 22:53 Comment(2)
Didn't know you could use filters in ifs. Cool :) I actually side-stepped the issue by using "None" as my false value instead..but good to know for future reference.Hairpiece
I try to learn something new every day... glad I could share ;-)Turnstile
A
10

In old version you can only use the ifequal or ifnotequal

{% ifequal YourVariable ExpectValue %}
    # Do something here.
{% endifequal %}

Example:

{% ifequal userid 1 %}
  Hello No.1
{% endifequal %}

{% ifnotequal username 'django' %}
  You are not django!
{% else %}
  Hi django!
{% endifnotequal %}

As in the if tag, an {% else %} clause is optional.

The arguments can be hard-coded strings, so the following is valid:

{% ifequal user.username "adrian" %} ... {% endifequal %} An alternative to the ifequal tag is to use the if tag and the == operator.

ifnotequal Just like ifequal, except it tests that the two arguments are not equal.

An alternative to the ifnotequal tag is to use the if tag and the != operator.

However, now we can use if/else easily

{% if somevar >= 1 %}
{% endif %}

{% if "bc" in "abcdef" %}
  This appears since "bc" is a substring of "abcdef"
{% endif %}

Complex expressions

All of the above can be combined to form complex expressions. For such expressions, it can be important to know how the operators are grouped when the expression is evaluated - that is, the precedence rules. The precedence of the operators, from lowest to highest, is as follows:

  • or
  • and
  • not
  • in
  • ==, !=, <, >, <=, >=

More detail

https://docs.djangoproject.com/en/dev/ref/templates/builtins/

Aboveground answered 18/7, 2013 at 11:45 Comment(1)
I don't see any mention of checking for False. Is False a supported keyword now?Hairpiece
B
6

Just ran into this again (certain I had before and came up with a less-than-satisfying solution).

For a tri-state boolean semantic (for example, using models.NullBooleanField), this works well:

{% if test.passed|lower == 'false' %} ... {% endif %}

Or if you prefer getting excited over the whole thing...

{% if test.passed|upper == 'FALSE' %} ... {% endif %}

Either way, this handles the special condition where you don't care about the None (evaluating to False in the if block) or True case.

Berty answered 8/10, 2012 at 19:6 Comment(0)
C
4

I have had this issue before, which I solved by nested if statements first checking for none type separately.

{% if object.some_bool == None %}Empty
{% else %}{% if not object.some_bool %}False{% else %}True{% endif %}{% endif %}

If you only want to test if its false, then just

{% if some_bool == None %}{% else %}{% if not some_bool %}False{% endif %}{% endif %}

EDIT: This seems to work.

{% if 0 == a|length %}Zero-length array{% else %}{% if a == None %}None type{% else %}{% if not a %}False type{% else %}True-type {% endif %}{% endif %}{% endif %}

Now zero-length arrays are recognized as such; None types as None types; falses as False; Trues as trues; strings/arrays above length 0 as true.

You could also include in the Context a variable false_list = [False,] and then do

{% if some_bool in false_list %}False {% endif %}
Colossus answered 19/11, 2010 at 21:9 Comment(5)
This differentiates between None and False but not [] which is also false.Hairpiece
Well I was dealing with a rendering a variable that was always NullBooleanField, (None/True/False). I believe you could extend it in the same fashion; e.g., {% if some_bool == [] %}{% else %} ... though at this point its starting to look very ugly and may be worthwhile to just to write your own template tag. docs.djangoproject.com/en/dev/howto/custom-template-tagsColossus
Does it even recognize []? It doesn't recognize False. Pretty sad that I'd have to write my own template tag for this :\Hairpiece
@Mark see edit above; you can do {% if 0 == a|length %} instead of {% if some_bool == [] %}. Actually tested and it works as expected.Colossus
Nice edit... that's certainly one way of doing it. Looks pretty nasty though :) I think a new template tag would be the lesser of evils.Hairpiece
J
4

Look at the yesno helper

Eg:

{{ myValue|yesno:"itwasTrue,itWasFalse,itWasNone" }}
Janot answered 27/11, 2013 at 10:49 Comment(1)
Nope. Pretty sure I wanted to put a whole block in there, not just a simple string.Hairpiece
M
3

I've just come up with the following which is looking good in Django 1.8

Try this instead of value is not False:

if value|stringformat:'r' != 'False'

Try this instead of value is True:

if value|stringformat:'r' == 'True'

unless you've been really messing with repr methods to make value look like a boolean I reckon this should give you a firm enough assurance that value is True or False.

Marrin answered 19/3, 2018 at 15:23 Comment(0)
D
2

This is far easier to check in Python (i.e. your view code) than in the template, because the Python code is simply:

myvar is False

Illustrating:

>>> False is False
True
>>> None is False
False
>>> [] is False
False

The problem at the template level is that the template if doesn't parse is (though it does parse in). Also, if you don't mind it, you could try to patch support for is into the template engine; base it on the code for ==.

Deviant answered 19/11, 2010 at 22:5 Comment(6)
But == False should work just as well. We don't need is, we just need it to recognize False as a keyword. I guess it would be easiest to this in the view as you suggested, but... it's annoying having all this one-off booleans cluttering up the place.Hairpiece
myvar is False is against PEP-8; the proper way is not myvarUdder
But doesn't == work in the same manner as is in this case? >>> False == False #(True) >>> None == False #(False) >>> [] == False #(False)Colossus
@ThiefMaster: But it isn't necessarily a boolean value. It's a boolean or a list. So it's necessary to differentiate.Hairpiece
0 is False is False, 0 == False is True - so as soon as you don't know your var is a bool, is is (no pun intended) probably not what you want.Udder
@ThiefMaster: Mark specifically said, "Note that I very specifically want check if it has the Python value False. This variable could be an empty array too, which is not what I want to check for." Which leads to my illustration above, which leads to is being the simplest solution that solves the problem.Deviant
A
1

you can use the int value of true and false

True = any int False = zero so, if we take an example:

{% if user.is_authenticated == 1 %}
do something
{% endif %}

this mean in python

if user.is_authenticated:
    #do something

and

{% if user.is_authenticated == 0 %}
do something
{% endif %}

this mean in python

if not user.is_authenticated :
    #do something    

OR equal

if !(user.is_authenticated) :
    #do something    

OR equal

if user.is_authenticated == False :
    #do something    
Allergist answered 13/2, 2022 at 15:2 Comment(0)
O
0

It can be done:if you use "select" tag.

{% if service.active == 0  %} selected {% endif%} 
Ossa answered 13/11, 2022 at 9:24 Comment(0)
A
-1

You can use if not to check if a variable is False in Django Template. *False is made by None, 0, [], {}, set(), range(0) and so on in Django Template same as Python and the doc explains more about if statement in Django Template:

{% if not myvar %}
Axiom answered 11/5, 2023 at 22:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.