我想制作GAE模型属性的属性。原因是在存储值之前将值转换为大写。对于一个普通的Python类,我会做如下操作:
Foo(db.Model):
def get_attr(self):
return self.something
def set_attr(self, value):
self.something = value.upper() if value != None else None
attr = property(get_attr, set_attr)
但是,GAE数据存储有自己的属性类概念,我研究了documentation,似乎我可以重写{model_instance
是什么,以及如何从中提取相应的字段。在
重写GAE属性类是提供getter/setter类功能的正确方法吗?如果是,怎么做?在
添加:
我认为重写get_value_for_datastore
的一个潜在问题是,在将对象放入数据存储之前,它可能无法被调用。因此,在存储对象之前获取属性将产生不正确的值。在
如果您希望在一个或多个模型中有多个具有类似行为的“字段”,那么将GAE的Property类进行子类化特别有用。别担心,
get_value_for_datastore
和make_value_from_datastore
将分别在任何存储和获取中被调用,因此如果您需要执行任何花哨的操作(包括但不限于将字符串大写,这并不是所有花哨的),在子类中重写这些方法就可以了。在编辑:让我们看看一些示例代码(净导入和
main
):这向您显示了字符串在数据存储中是大写的,但是如果您将
get
调用改为一个简单的mm = my
,您将看到内存中的实例没有受到影响。在但是,
db.Property
实例本身就是一个描述符,将其包装到内置的property
(一个完全不同的描述符)将不能很好地与数据存储一起工作(例如,您不能基于不是db.Property
的实例而是property
的实例的字段名编写GQL查询,这些字段在数据存储中不是。在因此,如果您想同时使用数据存储和来处理从未实际访问过数据存储的
Model
的实例,则必须为逻辑上“相同”的字段选择两个名称一个是将在内存模型实例中使用的属性的名称,其中一个可以是内置的property
;另一个是在数据存储中结束的属性的名称,它需要是db.Property
子类的一个实例,这是您在查询中需要使用的第二个名称。当然,作为名字基础的方法需要读写第二个名字,但是你不能仅仅“隐藏”后者,因为那是数据存储中的名字,所以这个名字对查询来说是有意义的!在你想要的是一个DerivedProperty。在那篇文章中概述了编写一个的过程-它与Alex描述的类似,但是通过重写get而不是get_value_for_数据存储,可以避免需要写入数据存储来更新它的问题。我的aetycoon库包含它和其他有用的属性。在
相关问题 更多 >
编程相关推荐