Django模板:如果为false?


70

如何使用Django模板语法检查变量是否为False

{% if myvar == False %}

似乎不起作用。

请注意,我非常想检查它是否具有Python值False。这个变量也可以是一个空数组,这不是我想要检查的。


首先,在模板上下文中具有既可以是列表又可以是布尔值的变量似乎是错误的方法?
Risadinha 2015年

@Risadinha我不记得我的用例了。你可能是对的。
mpen

1
{% if not myvar%}它肯定可以在Django 1.11中运行,但是我还没走多远!
伊波(Ibo)

@Ibo可以肯定地not myvar检查myvar是否为false,而不是False另请参阅
mpen

@mpen因此,如果myvar是布尔值,not myvarTrue无论其值(true或false)由render函数将其作为上下文变量发送到模板, 都会返回吗?在这种情况下,应该检查两件事:1-myvar提供给了render函数,2-提供了什么值myvar。如果myvar更多的是类实例,字典,对象等而不是经典变量,这将非常复杂。
伊波(Ibo)

Answers:


36

Django 1.10 (发行说明)在标签中添加了isis not比较运算符if。此更改使模板中的身份测试非常简单。

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'

如果您使用的是旧版Django,则从1.5版(发行说明)开始,模板引擎会将解释为TrueFalse并将None其解释为对应的Python对象。

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'

尽管它不能像人们期望的那样工作。

In[10]: compare_zero = Template("{% if zero == False %}0 == False{% endif %}")
In[11]: compare_zero.render(context)
Out[11]: u'0 == False'

1
会接受它,以便它
升到

当上下文变量包含整数0(零)时,我遇到了问题。由django渲染时,将其解释为“ False”。所以看起来我仍然需要像Gabriel Hurley建议的自定义模板标签。
ceasaro '16

或者您可以显式检查variable是否为0,但是模板标记可能不太冗长。
马丁

38

为了后代,我有几个 NullBooleanField,这是我的工作:

要检查是否True

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

要检查它是否正确False(请注意,这是可行的,因为只有3个值-True / False / None):

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

要检查是否None

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

我不确定为什么,但是我不能variable == False,但是我可以variable == None


1
一个更好的习惯用法(PEP 8的建议比较单调,如None,应始终使用isor is not,绝不等于运算符)来检查Nones是否在使用is,因为None是单例
Humphrey Bogart

17
@Beau:Django模板不是Python代码。在模板条件表达式中,这些不是“ is”运算符。
Ville Laurikari

这应该在某处的书中。很多人使用models.NullBooleanField()
罗伯·约翰斯通


23

您可以编写一个自定义模板过滤器,以执行六行代码:

from django.template import Library

register = Library()

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

然后在您的模板中:

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

当然,您可以使该模板标签更加通用……但这特别适合您的需求;-)


2
不知道您可以在中使用过滤器ifs。酷:)实际上,我通过使用“ None”作为我的错误值来避免了这个问题。
mpen 2010年

我每天都在尝试学习新的东西...很高兴能与大家分享;-)
Gabriel Hurley,2010年

10

在老版本中,你只能使用ifequalifnotequal

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

例:

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

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

与if标记中一样,{%else%}子句是可选的。

参数可以是硬编码的字符串,因此以下内容有效:

{%ifequal user.username“ adrian”%} ... {%endifequal%} ifequal标记的替代方法是使用if标记和==运算符。

ifnotequal与ifequal一样,只是它测试两个参数是否相等。

ifnotequal标记的替代方法是使用if标记和!=运算符。

但是,现在我们可以轻松地使用if / else了

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

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

复杂表达

可以将以上所有内容组合起来以形成复杂的表达式。对于此类表达式,了解对表达式求值时如何对运算符进行分组(即优先规则)非常重要。运算符的优先级从低到高依次为:

  • 要么
  • ==,!=,<,>,<=,> =

更多详情

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


2
我没有提到检查False。False现在是受支持的关键字吗?
mpen

6

再次遇到这个问题(一定是我以前遇到过的,并提出了一个不太令人满意的解决方案)。

对于三态布尔语义(例如,使用models.NullBooleanField),这很好用:

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

或者,如果您喜欢整个事情都感到兴奋...

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

无论哪种方式,这都可以处理特殊情况,即您不在乎None(如果在if块中评估为False)或True大小写。


与布尔字段完美配合!谢谢!
JDavies 2014年

4

我以前遇到过这个问题,我通过嵌套的if语句先分别检查none类型来解决。

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

如果您只想测试其是否为假,则只需

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

编辑:这似乎起作用。

{% 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 %}

现在零长度数组就是这样;无类型为无类型;假为假;真理如真理;长度大于0的字符串/数组为true。

您还可以在上下文中包含变量false_list = [False,],然后执行

{% if some_bool in false_list %}False {% endif %}

1
这可以区分NoneFalse但不是[],这也是错误的。
mpen 2010年

好吧,我正在处理一个始终为NullBooleanField(None / True / False)的变量的渲染。我相信您可以以相同的方式扩展它;例如,{%if some_bool == []%} {%else%} ... ...尽管此时它开始看起来很丑陋,可能值得只编写自己的模板标记。 docs.djangoproject.com/en/dev/howto/custom-template-tags
博士2010年

还能认出来[]吗?它不认识False。很遗憾我不得不为此编写自己的模板标签:\
mpen

@Mark参见上面的编辑;您可以执行{%if 0 == a | length%}而不是{%if some_bool == []%}。经过实际测试,可以正常工作。
jimbob博士2010年

很好的编辑……这当然是一种方法。虽然看起来很讨厌:)我认为一个新的模板标签将减少弊端。
mpen

4

看看yesno助手

例如:

{{ myValue|yesno:"itwasTrue,itWasFalse,itWasNone" }}

不。可以肯定的是,我想在其中放置一个完整的块,而不仅仅是一个简单的字符串。
mpen

3

我刚刚提出了以下内容,在Django 1.8中看起来不错

试试这个代替值不是False:

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

试试这个代替值是True:

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

除非您真的搞砸了repr方法以使值看起来像布尔值,否则我认为这应该给您足够的把握,确保值是True还是False。


2

使用Python(即您的视图代码)比使用模板要容易得多,因为Python代码很简单:

myvar is False

说明:

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

模板级别的问题是模板if无法解析is(尽管它可以解析in)。另外,如果您不介意,则可以尝试is将对支持的补丁修补到模板引擎中。基于的代码==


== False应该也一样。我们不需要is,我们只需要将其识别False为关键字即可。我想这在您看来建议的视图中最简单,但是...让所有这些一次性布尔值杂乱无章的地方真是令人讨厌。
mpen 2010年

1
myvar is False反对PEP-8;正确的方法是not myvar
ThiefMaster 2010年

但是==不能以这种情况下的相同方式工作吗?>>>错误==错误#(正确)>>>无==错误#(错误)>>> [] ==错误#(错误)
jimbob博士2010年

@ThiefMaster:但它并不一定是一个布尔值。这是布尔值列表。因此有必要区别对待。
mpen 2010年

0 is False是False,0 == False是True-因此,只要您不知道var是布尔值,is就(不是双关语)可能就不是您想要的。
ThiefMaster 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.