NDB:如何获取依赖于存储在父结构化属性上的值的子实体

时间:2014-03-15 11:58:07

标签: python app-engine-ndb

我有以下型号:

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 编辑只能看到一般创建的最后页面列表,而不是进入每本书。

有什么想法吗?

1 个答案:

答案 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实体会更小,维护成本更低