Setting Parent Key But Not Child Key While Using Endpoint-proto-datastore
Solution 1:
Following the keys_with_ancestors sample, let's assume we have the same imports and have defined the class MyParent
in the same way it is defined there.
The TL;DR answer is essentially that passing parent=
to the model constructor is equivalent to creating a key with None
as the last ID in the list of kind, ID pairs. For example, for a class MyModel
:
>>> parent = ndb.Key(MyModel, 1)
>>> child = MyModel(parent=parent)
>>> print child.key
ndb.Key('MyModel', 1, 'MyModel', None)
In order to do this with the sample, we could simply ignore the id
:
classMyModel(EndpointsModel):
_parent = None
attr1 = ndb.StringProperty()
attr2 = ndb.StringProperty()
created = ndb.DateTimeProperty(auto_now_add=True)
and in the setter simply set the half-baked key and don't try to retrieve from the datastore (since the key is not complete):
defParentSet(self, value):
ifnotisinstance(value, basestring):
raise TypeError('Parent name must be a string.')
self._parent = value
if ndb.Key(MyParent, value).get() isNone:
raise endpoints.NotFoundException('Parent %s does not exist.' % value)
self.key = ndb.Key(MyParent, self._parent, MyModel, None)
self._endpoints_query_info.ancestor = ndb.Key(MyParent, value)
Similarly, in the getter, you can just retrieve the parent directly from the key (though this doesn't guarantee there is only a single pair as the parent):
@EndpointsAliasProperty(setter=ParentSet, required=True)defparent(self):
if self._parent isNoneand self.key isnotNone:
self._parent = self.key.parent().string_id()
return self._parent
Having done this you won't need to change any of the API code and the example will work as expected.
Post a Comment for "Setting Parent Key But Not Child Key While Using Endpoint-proto-datastore"