Reputation: 1598
I have an ndb.Model which contains one Repeated property in it.
class Resort(ndb.Model):
name = ndb.StringProperty()
hotel_keys = ndb.KeyProperty(repeated=True)
I put a list of "keys" into "hotel_keys" property. Then I need to delete a single item in it (let's say by id) How could I do that?
resort = Resort.get_by_id(resort_id)
for hotel_key in resort.hotel.keys:
if hotel_key.id() == id:
del ???
resort.put()
I would appreciate any help. Thanks.
Upvotes: 1
Views: 2120
Reputation: 4278
I found that using the list's remove()
method works well:
if some_hotel_key in resort.hotel_keys:
resort.hotel_keys.remove(some_hotel_key)
resort.put()
Note that I'm using actual NDB Keys here, not key ID's. This assumes that the hotel_keys
property is a list of keys of some other model class, like. Like your Resort
class should be updated to have:
hotel_keys = ndb.KeyProperty(kind=Hotel, repeated=True)
And then be sure you have a class Hotel(ndb.Model)
defined somewhere. this would then let you define:
some_hotel_key = ndb.Key(Hotel, 'myHotel')
To reiterate a note I left above: it will only pop 1 instance of the value. If there's a risk your .hotel_keys
property has duplicates, be sure to handle that. I'd use resort.hotel_keys = list(set(resort.hotel_keys))
before getting the index for deletion.
Upvotes: 0
Reputation: 12986
THe repeated property is just a list, and the entity you are putting in the list is fairly simple. So you can just use pop and index rather than looping. The put()
dev~fish-and-lily> class Resort(ndb.Model):
... hotel_keys = ndb.KeyProperty(repeated=True)
...
dev~xxx-and-zzz> y = XX()
dev~xxx-and-zzz> y.hotel_keys.append(ndb.Key('abc',1))
dev~xxx-and-zzz> y.hotel_keys.append(ndb.Key('abc',2))
dev~xxx-and-zzz> y.hotel_keys.append(ndb.Key('abc',3))
dev~xxx-and-zzz> y.hotel_keys.index(ndb.Key('abc',3))
2
dev~xxx-and-zzz> y.hotel_keys.pop(2)
Key('abc', 3)
dev~xxx-and-zzz> y.hotel_keys
[Key('abc', 1), Key('abc', 2)]
dev~xxx-and-zzz>
Upvotes: 3
Reputation: 2276
Here is a way to delete it without iteration and remove: (only works for repeated keyproperty since it has an actualy string representation with single property id, for repeated structured property you'll have to loop and check against the property you want to delete get index and delete after the loop)
key_to_delete = ndb.Key(ModelOfThatId, id)
if key_to_delete in resort.hotel_keys:
idx = resort.hotel_keys.index(key_to_delete)
del resort.hotel_keys[idx]
resort.put()
Upvotes: 4
Reputation: 80340
Repeated properties are lists and iterating a list and removing a value from it at the same time is not possible. You should create a copy of the list without the value that you want removed - see this question: Remove items from a list while iterating
Upvotes: 2