我有以下型号:
class Roles(ndb.Model):
email = ndb.StringProperty(required=True)
type = ndb.StringProperty(choices=['writer', 'editor', 'admin']
class Book(ndb.Model):
uid = dnb.StringProperty(required=True)
user = ndb.UserProperty(auto_current_user_add=True)
name = ndb.StringProperty(required=True)
shared_with = ndb.StructuredProperty(Roles, repeated=True, indexed=True)
class Page(ndb.Model):
uid = dnb.StringProperty(required=True)
user = ndb.UserProperty(auto_current_user_add=True)
title = ndb.StringProperty(required=True)
parent_uid = ndb.ComputedProperty(lambda self: self.key.parent().get().uid)
shared_with = ndb.ComputedProperty(lambda self: self.key.parent().get().shared_with)
我使用的结构是:
Book1 Book2 - (parent)
| |
^ ^
pages pages - (child)
创建图书后, shared_with 会显示电子邮件/角色列表。
例如:
Book.uid = user.user_id()
Book.user = user
Book.name = "learning appengine NDB"
Book.shared_with = [Roles("user_1@domain.tld", "admin"), Roles("user_2@domain.tld", "editor")]
当用户创建页面时,user.user_id()
将存储为uid。
user_2@domain.tld(角色类型:编辑)创建页面时的示例:
Page.title = "understanding ComputedProperty"
Page.uid = user.user_id()
Page.user = user
使用这个模式,如果我只想显示给user_2@domain.tld他创建的页面,我可以通过uid过滤来做一个简单的查询,例如:
# supposing user_2@domain.tld is logged in
user2_pages = Page.query(Page.uid = user.user_id())
但对于本书的 shared_with 属性中列出的其他用户,我怎样才能继续展示他们自己(他们创建的页面),以及所有其他用户只有{{ 1}}(管理员,编辑)。
例如,如果我想允许其他用户( admins,editors );要查看为所有书籍创建的最后页面列表,我该如何执行查询?
到目前为止我一直在尝试的是使用 ComputedProperty ,我无法按预期工作。
要验证我是否获得了正确的值,我会执行以下查询:
Role
我确实得到了父uid,与shared.with值相同,但由于未知原因,我不能使用它们进行过滤,使用类似的东西:
query = Pages.query().get()
print query.parent_uid
一种可能更好,更简单的方法是每本书显示页面,但我想知道是否可以为所有书籍执行此操作,以便 admins 和编辑只能看到一般创建的最后页面列表,而不是进入每本书。
有什么想法吗?
答案 0 :(得分:0)
您的计算属性不起作用,因为它仅在放置Page实体时更新。见https://stackoverflow.com/a/12630991/1756187。对Book实体的任何更改都不会影响Page computed properties。
您可以尝试使用Model钩子来维护Page.shared_with。请参阅https://developers.google.com/appengine/docs/python/ndb/entities#hooks。
我想知道这是否是最佳方法。如果您在图书级别拥有共享信息,则可以使用其索引来检索图书密钥列表。你可以使用key only query来做到这一点。然后,您可以检索这些父键的所有页面的列表。这样,您根本不必将shared_with属性添加到Page模型中。查询的成本会稍微大一些,但是Page实体会更小,维护成本更低