有没有人知道在谷歌应用引擎中一种聪明的方式来返回一个只暴露一些原始属性的包装模型实例,并且不允许将实例保存回数据存储区?
我不是在寻找实际执行这些规则的方法,显然仍然可以通过挖掘__dict__
等来改变实例。我只是想要一种方法来避免意外暴露/改变数据
我最初的想法是这样做(我希望为User
模型的公开版本执行此操作):
class PublicUser(db.Model):
display_name = db.StringProperty()
@classmethod
def kind(cls):
return 'User'
def put(self):
raise SomeError()
不幸的是,GAE很早就将这种类型映射到了一个类,所以如果我PublicUser.get_by_id(1)
我实际上会得到一个User
实例,而不是PublicUser
个实例。
另外,我的想法是至少应该是Model
实例,以便我可以将它传递给不知道它是一个事实的代码“愚蠢”版本。最终我想这样做,以便我可以在只读版本上使用我的通用数据公开功能,这样他们只会公开有关用户的公共信息。
我选择了icio的解决方案。这是我编写的用于将属性从User
实例复制到PublicUser
实例的代码:
class User(db.Model):
# ...
# code
# ...
def as_public(self):
"""Returns a PublicUser version of this object.
"""
props = self.properties()
pu = PublicUser()
for prop in pu.properties().values():
# Only copy properties that exist for both the PublicUser model and
# the User model.
if prop.name in props:
# This line of code sets the property of the PublicUser
# instance to the value of the same property on the User
# instance.
prop.__set__(pu, props[prop.name].__get__(self, type(self)))
return pu
如果这不是一个好方法,请评论。
答案 0 :(得分:4)
你能否在你的User
类中创建一个实例化ReadOnlyUser
对象并在适当时复制成员变量值的方法?您的调用类似于User.get_by_id(1).readonly()
,其中readonly
方法的定义如下:
class User(db.Model):
def readonly(self):
return ReadOnlyUser(self.name, self.id);
或者您可以让您的User
类使用方法扩展另一个类,根据列出要复制的属性的静态变量或其他内容自动执行此操作。
P.S。我不用Python编码