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

时间:2016-06-17 17:22:23

标签: python django google-app-engine google-cloud-datastore app-engine-ndb

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

我的情况类似于带有帖子类型的CMS平台(比如WordPress),所以我有“博客”和“页面”。所有这些帖子类型都需要相同的属性集:父级,名称,Slug,模板,内容,状态和日期。

到目前为止,我认为我需要为这些创建一个模型:

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”属性)

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

  • 如何创建具有相同属性的多个模型(种类)?
  • 我是否复制&将上述模型粘贴在不同的类名下?
  • 是否可以动态创建新模型(类似于WordPress中的“自定义帖子类型”)?如果我使用ndb.Key('Blog', blogid)而不是声明模型,它是否有效?
  • 我是否创建了一个名为class PostType(ndb.Model)的模型,用于存储“帖子类型”并为其提供帖子的祖先? (如果我没有弄错,这会导致问题,因为更新帖子会“锁定”整个祖先树一秒钟左右)

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

更新

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

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下。如果我的查询变得混乱,我可能稍后决定将其更改为子类(每个“Post Type”单独kind)。谢谢大家的好建议!

2 个答案:

答案 0 :(得分:1)

  

如何创建具有相同属性的许多模型?

你可以继承:

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

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

  

是否可以动态创建新模型(类似于WordPress中的“自定义帖子类型”)?如果我使用ndb.Key('Blog', blogid)而不是声明模型,它是否有效?

我不是百分百肯定我明白你在这里问的是什么。 可以以与在python中动态创建类相同的方式动态创建模型(使用type),但您可能不希望这样做。获得那些动态创建的模型(并跟踪他们的名字)可能最终会给你带来严重的麻烦。

答案 1 :(得分:1)

基本上是一个简单的子类化示例,@ 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()

至于动态创建模型,来自Model Constructor doc:

  

应用程序通常不会调用Model(),但可能会调用   从Model继承的类的构造函数。这创造了一个新的   此模型的实例,也称为实体。

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