ThePloki ThePloki - 5 months ago 25
Python Question

GAE NDB Confused about Models and duplicating attributes

I'm trying to learn Google App Engine's NDB and I'm confused about the structure of models.

My situation is similar to a CMS platform with Post Types (like in WordPress), so I have "Blogs" and "Pages". All of these Post Types require the same set of attributes: Parent, Name, Slug, Template, Content, Status, and Date.

So far, I gather that I need to create a Model for these like this:

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)


(I'm using Expando because I will be adding "unknown" attributes in my application)

But with this structure, all of my posts (in every Post Type) will be within the same "kind", so queries will take longer (if I'm not mistaken).


  • How can I create many Models (kinds) with the same attributes?

  • Do I copy & paste the above Model under different class names?

  • 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?

  • Do I create a Model called
    class PostType(ndb.Model)
    that stores the "Post Types" and give them ancestors of Posts? (If I'm not mistaken, this would cause problems because updating a Post would "lock" the entire ancestor tree for a second or so)



My primary goal is efficiency. Thanks!

Updates:



As written by Dan and mgilson, adding sub-classes of the main Post class Model is a good way to solve this:

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


However, this requires writing the Models statically. Is there a way to accomplish this dynamically (without declaring them as Models beforehand)?

Answer

How can I create many Models with the same attributes?

You can subclass:

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

Though it's often easy enough to use the same kind and just add an extra field that represents the kind of post which you can filter on in queries.

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?

I'm not 100% sure that I understand what you're asking here. You can dynamically create models the same way you can dynamically create classes in python (using type), but you probably don't want to be doing this. Getting those dynamically created models (and keeping track of their names) will probably end up giving you serious headaches.

Comments