使用缓存扩展 appengine 的 db.Property
我正在寻找为 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
来自 code 我猜测谷歌正在使用 __get__()
和 __set__()
方法,这两个方法都将模型实例作为参数。这些可以在自定义类中使用吗? get_value_for_datastore
及其对应项有什么区别?
I'm looking to implement a property class for appengine, very similar to the existing db.ReferenceProperty
. I am implementing my own version because I want some other default return values. My question is, how do I make the property remember its returned value, so that the datastore query is only performed the first time the property is fetched? What I had is below, and it does not work. I read that the Property classes do not belong to the instances, but to the model definition, so I guess that the return value is not cached for each instance, but overwritten on the model every time. Where should I store this _resolved
variable?
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
Edit
Alex' answer is certainly usable. But it seems that the built-in db.ReferenceProperty
does store the _RESOLVED
variable on the model instance. As evidenced by:
[...]
setattr(model_instance, self.__resolved_attr_name(), value)
[...]
def __resolved_attr_name(self):
return '_RESOLVED' + self._attr_name()
The get_value_for_datastore
method is passed the model instance, but make_value_from_datastore
is not, so how do they find the _RESOLVED
property from that method?
Edit 2
From the code I gather that google is using the __get__()
and __set__()
methods, both of which do get the model instance as an argument. Are those usable in custom classes? What is the difference with get_value_for_datastore
and its counterpart?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
PageProperty
实例存在于每个模型中,而不是每个实体中(其中实体是模型类的实例)。所以我认为你需要一个映射页面名称的字典 ->页面实体,而不是每个 PageProperty 实例的单个属性。例如,也许像...:A
PageProperty
instance exists per-model, not per-entity (where an entity is an instance of the model class). So I think you need a dictionary that maps pagename -> Page entity, instead of a single attribute per PageProperty instance. E.g., maybe something like...:如果您只想更改 ReferenceProperty 行为的一小部分,您可能只想扩展它,覆盖它的default_value 方法。您可能会发现 ReferenceProperty 的来源具有指导意义。
If you only want to change some small part of the behaviour of ReferenceProperty, you may want to simply extend it, overriding its default_value method. You may find the source for ReferenceProperty to be instructive.