在Django模板中迭代Expando的动态属性

3 投票
1 回答
922 浏览
提问于 2025-04-16 02:12

我正在尝试遍历一个动态模型的属性,以便输出它们。有没有其他方法可以做到这一点,而不是像这样自己创建一个方法:

class Event(db.Expando):
    platform = db.ReferenceProperty(Platform)
    date = db.DateTimeProperty()

    def getValues(self):
        return self._dynamic_properties

然后在模板中——这个模板接收一个叫做'platform'的对象:

{% for event in platform.event_set %}
    <b>{{ event.date }}</b><br />
    {% for pair in event.getValues.items %}
        {{ pair.0 }} = {{ pair.1 }}<br />
    {% endfor %}
{% endfor %}

这样做是有效的,但我很惊讶我不能直接这样做:

{% for event in platform.event_set %}
    <b>{{ event.date }}</b><br />
    {% for pair in event.items %}
        {{ pair.0 }} = {{ pair.1 }}<br />
    {% endfor %}
{% endfor %}

而不需要自己调用一个方法……我是不是应该用其他的东西,而不是'.items'?

1 个回答

0

你可以使用数据库模型中的 'dynamic_properties' 方法来获取一个扩展对象的属性,这个方法返回的格式和 'properties' 方法是一样的(具体可以查看 模型类的文档)。

不过要记住,这些函数并不会返回属性的具体值... 'properties' 方法返回的是一个字典,里面包含了属性名称和它们对应的实现类(在这个例子中是 db.ReferenceProperty 和 db.DateTimeProperty),而 'dynamic_properties' 只是返回一个属性名称的列表,因为扩展对象无法将动态值映射到实现类。

如果你想获取属性的值,你需要使用 getattr(model, prop_name)。在 Django 模板中没有办法直接运行这个函数(除非使用 自定义标签库),不过你可以这样保存并重写你的方法...

def getExpandoValues(self):
   return dict((name, getattr(self, name)) for name, impl_class in self.dynamic_properties())

... 然后重写你的模板,通过新的字典输入来访问这些值:

{% for event in platform.event_set %}
  <b>{{ event.date }}</b><br />
  {% for pair in event.getExpandoValues %}
     {{ pair.0 }} = {{ pair.1 }}<br />
  {% endfor %}
{% endfor %}

撰写回答