GAE NDB 对模型和重复属性感到困惑

GAE NDB Confused about Models and duplicating attributes

我正在尝试学习 Google App Engine 的 NDB,但我对模型的结构感到困惑。

我的情况类似于具有 Post 类型的 CMS 平台(如在 WordPress 中),所以我有 "Blogs" 和 "Pages"。所有这些 Post 类型都需要相同的属性集:Parent、Name、Slug、Template、Content、Status 和 Date。

到目前为止,我认为我需要为这样的对象创建一个模型:

class Post(ndb.Expando):
    parent = ndb.StringProperty()
    name = ndb.StringProperty()
    slug = ndb.StringProperty()
    template = ndb.StringProperty()
    content = ndb.StringProperty(indexed=False)
    status = ndb.StringProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

(我正在使用 Expando,因为我将在我的应用程序中添加 "unknown" 属性)

但是使用这种结构,我所有的帖子(在每个 Post 类型中)都将在同一个 "kind" 中,因此查询将花费更长的时间(如果我没记错的话)。

我的主要目标是效率。谢谢!

更新:

正如 Dan 和 mgilson 所写,添加主要 Post class 模型的子 class 是解决此问题的好方法:

class Post(ndb.Expando):
    parent = ndb.StringProperty()
    name = ndb.StringProperty()
    slug = ndb.StringProperty()
    template = ndb.StringProperty()
    content = ndb.StringProperty(indexed=False)
    status = ndb.StringProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

class Blog(Post):
    pass

但是,这需要静态编写模型。有没有办法动态地完成此操作(无需事先将它们声明为模型)?

更新:

根据下面给出的建议,我决定将我所有的实体都放在同一个 kind 下。如果我的查询变得混乱,我可能稍后决定将其更改为 subclasses(每个 "Post Type" 有单独的 kinds)。谢谢大家的宝贵建议!

How can I create many Models with the same attributes?

您可以继承:

class SpecialPost(Post):
    """Special post type that is a different kind than Post."""

虽然通常很容易使用相同的种类,只需添加一个额外的字段来表示您可以在查询中过滤的 post 的种类。

Is it possible to create new Models dynamically (similar to "Custom Post Types" in WordPress)? Does it work if I use ndb.Key('Blog', blogid) instead of declaring a Model?

我不是 100% 确定我理解你在这里问的问题。您 可以 动态创建模型,就像您可以在 python 中动态创建 类 一样(使用 type),但您可能不想做这个。获取那些动态创建的模型(并跟踪它们的名称)可能最终会让您非常头疼。

基本上是一个简单的子类化示例,@mgilson 已经提到过。

class Post(ndb.Expando):
    parent = ndb.StringProperty()
    name = ndb.StringProperty()
    slug = ndb.StringProperty()
    template = ndb.StringProperty()
    content = ndb.StringProperty(indexed=False)
    status = ndb.StringProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

class Blog(Post):
    someint = ndb.IntegerProperty()

blog = Blog(status='new', someint=2)
key = blog.put()
print key.kind()

关于动态创建模型,来自模型的 Constructor 文档:

An application won't normally call Model(), but is likely to call the constructor of a class that inherits from Model. This creates a new instance of this model, also known as an entity.

即使可能(我没有深入挖掘 ndb/models.py 可以肯定地说它不是),它似乎也不是一件清楚的事情。就个人而言,我会远离它,而是重新考虑对这种动态创建模型的需求。