Настройка родительского ключа, но не дочернего ключа при использовании конечного объекта-протодастора

Как установить родительский / предковый объект для конечной точки и присвоить идентификатор / ключ объекта автоматически с помощью хранилища данных?

Я попытался адаптировать образец keys_with_ancestors, но, похоже, ударил бит блока, потому что он требует указать как id, так и родительский. Я хотел бы сделать что-то подобное, кроме как предоставить только родительский идентификатор или ключ и иметь идентификатор / ключ сущности, автоматически сгенерированный хранилищем данных приложения.

Ниже показано, как я буду делать это, используя только NDB.

class Parent(ndb.Model): name = ndb.StringProperty() class MyModel(ndb.Model): attr1 = ndb.StringProperty() attr2 = ndb.StringProperty() p = Parent(name="Jerry") p_key = p.put() # or retrieve the key from somewhere else mod = MyModel(parent=p_key) mod.put() 

Возможно ли это, и кто-то может указать мне в правильном направлении? Благодарю.

Следуя образцу keys_with_ancestors , предположим, что у нас есть те же самые MyParent и он определил класс MyParent же, как он определен там.

Ответ TL, DR по существу состоит в том, что передача parent= конструктору модели эквивалентна созданию ключа с None в качестве последнего идентификатора в списке видов, пары идентификаторов. Например, для класса MyModel :

 >>> parent = ndb.Key(MyModel, 1) >>> child = MyModel(parent=parent) >>> print child.key ndb.Key('MyModel', 1, 'MyModel', None) 

Чтобы сделать это с образцом, мы могли бы просто игнорировать id :

 class MyModel(EndpointsModel): _parent = None attr1 = ndb.StringProperty() attr2 = ndb.StringProperty() created = ndb.DateTimeProperty(auto_now_add=True) 

и в сеттере просто установите полузакрытый ключ и не пытайтесь извлечь из хранилища данных (поскольку ключ не завершен):

  def ParentSet(self, value): if not isinstance(value, basestring): raise TypeError('Parent name must be a string.') self._parent = value if ndb.Key(MyParent, value).get() is None: 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) 

Аналогично, в getter вы можете просто получить родителя непосредственно из ключа (хотя это не гарантирует наличие только одной пары в качестве родителя):

  @EndpointsAliasProperty(setter=ParentSet, required=True) def parent(self): if self._parent is None and self.key is not None: self._parent = self.key.parent().string_id() return self._parent 

Сделав это, вам не нужно будет менять какой-либо код API, и пример будет работать так, как ожидалось.