【问题标题】:Can variables with lookups be used in Django {% ifequal %} expressions?可以在 Django {% ifequal %} 表达式中使用带有查找的变量吗?
【发布时间】:2012-05-01 08:03:33
【问题描述】:

这是我的代码:

[{{thing.syncedthing_set.all.0.state}}]
{% ifequal thing.syncedthing_set.all.0.state "InProgress" %}
    It worked
{% endifequal %}

结果:

[InProgress]

换句话说,变量查找有效,但没有通过“ifequal”测试。除了不支持变量查找之外,我想不出任何原因这不起作用。

2007 年的邮件列表消息说当时不支持它们:https://groups.google.com/forum/?fromgroups#!topic/django-users/oU1im3UTcLc - 现在仍然如此吗?

如果是这样,有什么好的解决方法吗?在这种情况下,修改调用模板的 Python 代码并不容易。

如果它们应该起作用 - 还有其他可能的原因吗?

this very similar question,但答案对我不起作用。我正在使用 Django 1.3。

编辑

好的,所以“状态”具有类型类。查找定义,状态指的是最终子类模型的类。字段:

class FSMField(models.Field):
    __metaclass__ = models.SubfieldBase

    states = {}
    """ Contains { 'Statename': StateClass, ... }"""

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('max_length', 50)
        super(FSMField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if isinstance(value, State):
            return value
        return self.__class__.states.get(str(value))()

    def get_prep_value(self, value):
        return str(value)

    def get_internal_type(self):
        return 'CharField'

鉴于此 - 我实际上不确定如何在模板系统中获取真正的字符串值。原谅我的新手。

EDIT2 实际上,相关位可能是“状态”类本身:

class State(object):
    """ A simple finite statement machine abstract class, with on_entry and on_exit events."""
    def __unicode__(self):
        return "%s" % (self.__class__.__name__)

    def __str__(self):
        return "%s" % (self.__class__.__name__)

【问题讨论】:

  • thing.syncedthing_set.all.0.state 的类型是什么?你能在 Django shell 中显示它吗?
  • 顺便说一句 - 我原来的问题的答案是“是”。

标签: python django django-templates


【解决方案1】:

对象的字符串表示形式与其实际表示形式之间存在差异。似乎您的state 属性返回了一个其unicode 表示为InProgress 的对象,但这并不意味着它实际上等于"InProgress"。例如,如果 state 是另一个模型的 ForeignKey,这将是正确的 - 在这种情况下,您可以在查找中添加另一个级别以获取返回该状态的实际字段。

更新后编辑不幸的是,我认为你已经把自己编码到了一个角落。由于没有将状态包含为字符串的实际实例属性,因此无法通过字符串比较来获取它。

我想到了几种可能性。一种是将所有可能的State 子类传递给模板上下文(可能通过上下文处理器),之后您就可以将state 与实际对象进行比较。这太可怕了。

另一种方法是在State 类或模型上添加一个函数,它将状态作为字符串。这可以像现有的__unicode__ 方法一样简单(您实际上不能使用它,因为模板语言禁止访问以下划线开头的属性)。然后你可以做ifequal foo.bar.0.state.as_string "InProgress" 或其他什么,这将调用as_string() 方法,你的比较就会成功。

【讨论】:

  • 是的。所以,看看我更新的问题 - 该类是字段的子类,所以它应该像 CharField 一样,对吧?在这种情况下,如何在模板系统中获取该字符串值?
  • 哦,太棒了。这很完美。 [要清楚 - 我可以修改状态类。我无法(轻松)修改调用模板的位置。]
【解决方案2】:

尝试使用 IF:

{% if thing.syncedthing_set.all.0.state == "InProgress" %}

【讨论】:

  • 同样的结果。原来这个值实际上是一个类 - 谢谢@okm。
猜你喜欢
  • 2014-08-24
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 2016-02-12
相关资源
最近更新 更多