我正在寻找为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
属性?
我收集的code谷歌正在使用__get__()
和__set__()
方法,这两种方法都将模型实例作为参数。那些可用于自定义类吗?与get_value_for_datastore
及其对应物有什么区别?
答案 0 :(得分:2)
每个模型存在PageProperty
个实例,而不是每个实体(其中实体是模型类的实例)。所以我认为你需要一个映射页面名称的字典 - >页面实体,而不是每个PageProperty实例的单个属性。例如,可能是......:
class PageProperty(db.Property):
data_type = Page
def __init__(self, *a, **k):
super(PageProperty, self).__init__(*a, **k)
self._mycache = {}
def get_value_for_datastore(self, model_instance):
page = super(PageProperty, self).get_value_for_datastore(model_instance)
name = page.key().name()
self._mycache[name] = page
return name
def make_value_from_datastore(self, value):
if value not in self._mycache:
self._mycache[value] = Page.get_by_name(value)
return self._mycache[value]
答案 1 :(得分:1)
如果您只想更改ReferenceProperty行为的一小部分,您可能只想扩展它,覆盖其default_value方法。您可能会发现ReferenceProperty的the source具有指导性。