3

I'm trying to iterate through an Expando-Model's dynamic properties in order to output them all. Is there a way of doing this other than creating your own method like such:

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

    def getValues(self):
        return self._dynamic_properties

And then in the template - which is passed a 'platform' object:

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

This works, but I'm suprised I can't just do:

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

Without having my own method call... should I use something other than '.items'?

Wex
  • 4,434
  • 3
  • 33
  • 47
  • Does {% for pair in event._dynamic_properties.items %} not work? – Drew Sears Aug 02 '10 at 18:09
  • No; there was someone who suggested that but the answer has been withdrawn. It's not possible to access properties that start with an underscore. Cheers for the suggestion. – Wex Aug 03 '10 at 10:26

1 Answers1

0

You can use a db.Model's 'dynamic_properties' method to retrieve an Expando's properties, in the same format as the 'properties' method (as documented under the Model class)

Remember that those functions don't return a property's value, though... 'properties' returns a dictionary of property names mapped to their implementation class (db.ReferenceProperty and db.DateTimeProperty, in this case), and 'dynamic_properties' simply returns a list of property names, since Expandos can't map a dynamic value to an implementation class.

In order to get the property's value, you have to use getattr(model, prop_name). There is no way to run this function purely inside a Django template (without a custom tag library), but you could keep and re-write your method like so...

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

... and re-write your template to access the values via the new dictionary input:

{% for event in platform.event_set %}
  <b>{{ event.date }}</b><br />
  {% for pair in event.getExpandoValues %}
     {{ pair.0 }} = {{ pair.1 }}<br />
  {% endfor %}
{% endfor %}
Community
  • 1
  • 1
Sam Gammon
  • 1,457
  • 10
  • 16