Я хочу реализовать класс свойств для appengine, очень похожий на существующий db.ReferenceProperty
. Я реализую свою собственную версию, потому что я хочу некоторые другие возвращаемые значения по умолчанию. Мой вопрос: как заставить свойство запомнить возвращаемое значение, чтобы запрос хранилища данных выполнялся только при первом получении свойства? То, что у меня было ниже, и это не работает. Я прочитал, что классы Property принадлежат не экземплярам, а определению модели, поэтому я предполагаю, что возвращаемое значение не кэшируется для каждого экземпляра, а каждый раз перезаписывается в модели. Где должен Я храню эту _resolved
переменную?
class PageProperty(db.Property):
data_type = Page
def get_value_for_datastore(self, model_instance):
page = super(PageProperty, self).get_value_for_datastore(model_instance)
self._resolved = page
return page.key().name()
def make_value_from_datastore(self, value):
if not hasattr(self, '_resolved'):
self._resolved = Page.get_by_name(value)
return self._resolved
Редактировать
Ответ Алекса, безусловно, пригоден для использования. Но, похоже, что встроенная db.ReferenceProperty
действительно сохраняет переменную _RESOLVED
в экземпляре модели. Как свидетельствуют:
[...]
setattr(model_instance, self.__resolved_attr_name(), value)
[...]
def __resolved_attr_name(self):
return '_RESOLVED' + self._attr_name()
Метод get_value_for_datastore
передается экземпляру модели, но make_value_from_datastore
нет, так как они находят свойство _RESOLVED
из этого метода?
Редактировать 2
Из кода я понял, что Google использует методы __get__()
и __set__()
, которые оба получают экземпляр модели в качестве аргумента. Это можно использовать в пользовательских классах? В чем разница с get_value_for_datastore
и его аналогом?