views:

469

answers:

5

I have a model class:

class Person(db.Model):
  first_name = db.StringProperty(required=True)
  last_name = db.StringProperty(required=True)

I have an instance of this class in p, and string s contains the value 'first_name'. I would like to do something like:

print p[s]

and

p[s] = new_value

Both of which result in a TypeError.

Does anybody know how I can achieve what I would like?

+1  A: 
getattr(p, s)
setattr(p, s, new_value)
Jim
Hey Jim, thanks for you reply. The above code results in an AttributeError.
David Sykes
+1  A: 

Try:

p.model_properties()[s].get_value_for_datastore(p)

See the documentation.

Jim
Would that even work? model_properties is a class method, not an instance method.
Antti Rasinen
Thank you, you put me on the correct path. The exact answer is p.properties()[s].get_value_for_datastore(p)
David Sykes
+3  A: 

If the model class is sufficiently intelligent, it should recognize the standard Python ways of doing this.

Try:

getattr(p, s)
setattr(p, s, new_value)

There is also hasattr available.

Antti Rasinen
I've used GAE and getattr and setattr work fine.
Dave Webb
Dave, is it possible there is a difference between the db.Model and db.Expando classes?
David Sykes
+2  A: 

With much thanks to Jim, the exact solution I was looking for is:

p.properties()[s].get_value_for_datastore(p)

To all the other respondents, thank you for your help. I also would have expected the Model class to implement the python standard way of doing this, but for whatever reason, it doesn't.

David Sykes
Why use get_value_for_datastore? If you want the same representation you'd get from p.first_name, you shouldn't be calling that.
Nick Johnson
A: 

p.first_name = "New first name" p.put()

or p = Person(first_name = "Firsty", last_name = "Lasty" ) p.put()

jamtoday