staffordrj
staffordrj

Reputation: 23

How do I select an ndb property with a string?

With a data model like this

class M(ndb.Model):
    p1 = ndb.StringProperty()
    p2 = ndb.StringProperty() 
    p3 = ndb.StringProperty()

I'm trying to set the property values with a loop something like this

list = ["a","b","c", "d"]
newM = M( id = "1234" )
for p in ['p1','p2','p3']:
    newM[p] = choice(list)
newM.put()

But I get an error

ERROR 'M' object does not support item assignment

Is there a way to do this without explicitly defining each property?

Upvotes: 2

Views: 614

Answers (2)

Tim Hoffman
Tim Hoffman

Reputation: 12986

p1, p2, p3 are defined as attributes of the model, and models do not support setitem or getitem access (i.e the model does not behave like a dictionary). As the other answer suggests using setattr, which will work. However just occasionally that can cause a problem, depending on the type you are trying do the setattr with. An other alternative is to use _set_value which looks like

for prop in M._properties.values():
    prop._set_value(newM,choice(list)

or if you only want specific properties rather than all.

clist= ["a","b","c", "d"]
newM = M( id = "1234" )
for p in ['p1','p2','p3']:
    M._properties[p]._set_value(newM,choice(clist))
newM.put()

Something else to consider, list is a built in type, and you should not assign values to it.

Upvotes: 1

Greg
Greg

Reputation: 10360

python has setattr which will do what you want. Inside your loop:

setattr(newM, p, choice(list)

Upvotes: 3

Related Questions