【问题标题】:Django templatetag return True or FalseDjango 模板标签返回 True 或 False
【发布时间】:2013-11-28 17:14:19
【问题描述】:

我正在覆盖 Django 中管理模板的 index.html。 我想在侧边栏上添加一个额外的字段,只有在条件为真时才会显示。

这里是m index.html的重要部分:

{% block sidebar %}
<div id="content-related">
{% if action_needed %}
    <div class="my-module">
        <h2>Foobar</h2>
        <p>Display this over the sidebar</p>
    </div>
{% endif %}
... Sidebarstuff...
{% endblock %}

这是我的模板标签:

@register.simple_tag
def action_needed():
    if some_conditon:
        return True
    else:
        return False

问题是,我的模块一直显示。 在另一个线程中,我读到了有关使用过滤器而不是模板标签的信息,但 Django 文档说,过滤器至少需要一个参数。但我只是想要一个真/假的回报。

最好的方法是什么?

编辑: 这里有更多代码向您展示我到底在做什么: 如果帐户过期,我有一个模型帐户,它有一个 DateTimeField expire_date 来存储。

exp = Account.objects.filter(expiration_date__lte = timezone.now())
if len(exp) == 0:
    return False
else:
    return True

编辑2: 我解决了它,但我不知道这是否是一种非常优雅的方式。由于我没有足够的声誉来回答我自己的问题,我需要在这里分享我的解决方案:

如果条件为真,我将如果 my-module 的 HTML 代码放在模板标签中并返回它:

@register.simple_tag
def action_needed():
    if some_conditon:
        return '<div class="my-module"><h2>Foobar</h2><p>Display this over the sidebar</p></div>'
    else:
        return ''

现在我只是在模板中调用

{% action_needed %}

【问题讨论】:

  • 什么是some_condition?它取决于什么?
  • 它不依赖任何东西。只需检查我的数据库中是否有模型的对象
  • 如果您创建了过滤器,则可以将数据库中正在检查的模型的名称作为参数传递

标签: python django django-templates django-admin


【解决方案1】:

您的第一种方法(action_needed 标签返回布尔值 + if 标签)不起作用,因为模板标签不能用作另一个模板标签的“参数”,因此您的 {% if action_needed %} 尝试解决 在上下文中名为action_needed 的变量

如果测试(“some_condition”)依赖于当前上下文中可用的某个对象,您可以使用应用于该对象的自定义过滤器,即:

@register.filter
def action_needed(obj):
    return some_test_on(obj)

{% if obj|action_needed %}
   whatever
{% endif %}

否则,您要么必须编写一个赋值标签,在上下文中设置标志,然后测试标志,要么就像您最终所做的那样,编写一个标签来进行测试并返回适当的 html sn-p。

顺便说一句——这个:

exp = Account.objects.filter(expiration_date__lte = timezone.now())
if len(exp) == 0:
    return False
else:
    return True

这是一种复杂的写法:

return len(Account.objects.filter(expiration_date__lte=timezone.now())) > 0

这是一种低效的写法:

return Account.objects.filter(expiration_date__lte=timezone.now()).exists()

【讨论】:

  • 那么,我的解决方案可以吗?如果您知道我的意思,我认为这可能有点“糟糕的风格”..
  • 有模板标签生成 html sn-ps 是可以的,是的。至于是否最好使用分配标签在上下文中设置一个标志,然后测试该标志并做出相应的行为,或者让模板标签同时处理测试和生成 html(或纯文本或其他)sn-p ,这实际上取决于具体的用例和您自己的喜好。我在这里唯一的观察是关于命名 - action_needed 是谓词的好名称,但对于包含标记则不是。
  • assignmenttag 效果很好!谢谢。
【解决方案2】:

您可以在这里采取一些方法。一种想法是将some_condition 检查作为上下文处理器,因此它会自动包含在所有模板中 - 尽管如果您只希望在一个模板中使用它,那就有点过头了。

更好的方法是使用包含标签。这样,{% if action_needed %} 标记中当前的代码将位于单独的模板 sn-p 中,仅当条件为真时才会包含该模板。或者,您可以使用赋值标记在上下文中设置变量,然后在if 中检查它。

(另外,请注意您的代码效率极低,因为它可能涉及获取所有未来的Account 对象。您应该使用if exp.exists() 来进行简单的存在性检查。)

【讨论】:

  • 感谢您的帮助。我用另一种方式解决了它。问题是,我无法回答自己的问题,因为我没有足够的声誉......
【解决方案3】:

您可以创建一个自定义模板标签来检查是否满足条件。如果为真,则在标签之间呈现 html。

{% block sidebar %}
<div id="content-related">
{% ifaction %}
    <div class="my-module">
        <h2>Foobar</h2>
        <p>Display this over the sidebar</p>
    </div>
{% endifaction %}
... Sidebarstuff...
{% endblock %}

您可以通过查看 Gargoyle 的代码来了解它是如何完成的 ifswitch tag.

【讨论】:

  • 这不正是我已经在做的吗?您只删除了 {% if action %} 之间的空格
  • 我的意思是你创建了一个名为 ifaction 的自定义模板标签,而不是使用标准的 django if 模板标签。
猜你喜欢
  • 2013-03-18
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2011-07-28
  • 2013-09-22
  • 2012-02-21
相关资源
最近更新 更多