【问题标题】:Django templates: If false?Django模板:如果是假的?
【发布时间】:2011-05-12 20:59:36
【问题描述】:

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

{% if myvar == False %}

好像没用。

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

【问题讨论】:

  • 在模板上下文中有一个既可以是列表也可以是布尔值的变量似乎首先是错误的方法?
  • @Risadinha 我不记得我的用例了。你可能是对的。
  • {% if not myvar%} 肯定可以在 Django 1.11 中使用,不过我不知道你能走多远!
  • @Ibo 很确定 not myvar 检查 myvar 是否为假,而不是 Falsesee also
  • @mpen 所以如果myvar 是一个布尔值,not myvar 将返回True,如果它被渲染函数作为上下文变量发送到模板,无论其值如何(true 或 false )?在这种情况下,应该检查两件事:1-myvar 提供给渲染函数,2-如果提供了 myvar 的值。如果myvar 更像是类实例、字典、对象等而不是经典变量,这将非常复杂。

标签: django django-templates


【解决方案1】:

为了后代,我有几个NullBooleanFields,这就是我所做的:

检查是否为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

【讨论】:

  • 一个更好的习惯用法(recommended by PEP 8比较像 None 这样的单例应该始终使用 isis not,而不是相等运算符)来检查 @ 987654333@s 使用is,因为 None 是单例
  • @Beau:Django 模板不是 Python 代码。这些不是模板条件表达式中的“is”运算符。
  • 这应该在某本书的某个地方。很多人使用models.NullBooleanField()
【解决方案2】:

Django 1.10 (release notes)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 开始,(release notes) 模板引擎会将 TrueFalseNone 解释为相应的 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'

【讨论】:

  • 将接受这一点,以便它移动到顶部,其他使用当前版本的人可以找到它:-)
  • 当我的上下文变量包含整数 0(零)时,我遇到了问题。当它被 django 渲染时,它被解释为“假”。所以看起来我仍然需要像 Gabriel Hurley 建议的那样自定义模板标签。
  • 或者您可以明确检查变量是否为0,但模板标签可能不那么冗长。
【解决方案3】:

我认为这对你有用:

{% if not myvar %}

【讨论】:

  • 该问题特别提到了仅检查False 值并且应该由空数组触发。这适用于两者。
【解决方案4】:

您可以编写一个自定义模板过滤器,用六行代码完成此操作:

from django.template import Library

register = Library()

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

然后在你的模板中:

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

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

【讨论】:

  • 不知道您可以在ifs 中使用过滤器。酷 :) 我实际上通过使用“无”作为我的错误值来回避这个问题。但很高兴知道以供将来参考。
  • 我每天都在努力学习新的东西......很高兴我能分享 ;-)
【解决方案5】:

在旧版本中,您只能使用 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 标记和 == 运算符。

如果不相等 就像 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/

【讨论】:

  • 我没有看到任何关于检查 False 的内容。 False 现在是受支持的关键字吗?
【解决方案6】:

刚刚又遇到了这个问题(我以前确实遇到过,但想出了一个不太令人满意的解决方案)。

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

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

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

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

无论哪种方式,这都会处理您不关心 None(在 if 块中评估为 False)或 True 情况的特殊情况。

【讨论】:

  • 与布尔字段完美配合!谢谢!
【解决方案7】:

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

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

现在零长度数组被识别为这样; None 类型为 None 类型;假为假;真如真;长度大于 0 的字符串/数组为真。

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

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

【讨论】:

  • 这区分 NoneFalse 但不是 [] 这也是错误的。
  • 好吧,我正在处理一个始终为 NullBooleanField(无/真/假)的变量的渲染。我相信你可以用同样的方式扩展它;例如,{% if some_bool == [] %}{% else %} ...尽管此时它开始看起来非常难看,并且可能值得编写自己的模板标签。 docs.djangoproject.com/en/dev/howto/custom-template-tags
  • 它还能识别[]吗?它无法识别False。很遗憾我不得不为此编写自己的模板标签:\
  • @Mark 参见上面的编辑;您可以使用 {% if 0 == a|length %} 而不是 {% if some_bool == [] %}。经过实际测试,它按预期工作。
  • 不错的编辑...这当然是一种方法。不过看起来很讨厌 :) 我认为一个新的模板标签将是少有的坏事。
【解决方案8】:

查看yesno 助手

例如:

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

【讨论】:

  • 不。很确定我想把整个块放在那里,而不仅仅是一个简单的字符串。
【解决方案9】:

我刚刚提出了以下在 Django 1.8 中看起来不错的方法

试试这个而不是 value is not False:

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

试试这个,而不是值为 True:

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

除非你真的用 repr 方法让 value 看起来像一个布尔值,否则我认为这应该给你足够坚定的保证 value 是 True 或 False。

【讨论】:

    【解决方案10】:

    这比在模板中检查 Python(即您的视图代码)要容易得多,因为 Python 代码很简单:

    myvar is False
    

    说明:

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

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

    【讨论】:

    • 但是== False 应该也能正常工作。我们不需要is,我们只需要将False 识别为关键字。我想按照您的建议,在视图中这将是最简单的,但是......让所有这些一次性布尔值混乱的地方很烦人。
    • myvar is False 反对 PEP-8;正确的方法是not myvar
    • 但是 == 的工作方式与本例中的工作方式不同吗? >>> False == False #(True) >>> None == False #(False) >>> [] == False #(False)
    • @ThiefMaster:但它不是一定是布尔值。这是一个布尔 列表。所以需要区分。
    • 0 is False 是 False,0 == False 是 True - 所以一旦你不知道你的 var 是一个布尔值,is 可能不是你想要的。
    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2012-01-03
    相关资源
    最近更新 更多