如何在使用App Engine创建模型类时要求key_name?

2 投票
3 回答
518 浏览
提问于 2025-04-16 03:53

我想让我的一个模型类必须指定我自己定义的键名,这样我就可以确保它总是存在。请问我该怎么做呢?比如,我可能有一个这样的模型类:

class Account(db.Model):
    user = db.UserProperty(required=True)
    email = db.EmailProperty()

我希望强制要求总是指定这个键名,要求实例化时必须像下面这样:

    user_obj = users.get_current_user()
    new_user = Account(user=user_obj, key_name=user.user_id())
    new_user.put()

这个怎么实现呢?提前谢谢!

3 个回答

0

这里有另一个例子,讲的是如何要求并验证一个叫做 key_name 的属性:在 Google App Engine 数据存储中,模型的 key_name 属性的验证器(Python)

2

你可以像在jaikuengine上那样创建一个基础类,类似于模型。

class BaseModel (db.Model):
    def __init__(self, parent=None, key_name=None, _app=None, **kw):
        if not key_name and 'key' not in kw:
            key_name = self.key_from(**kw)

        super(BaseModel, self).__init__(
            parent, key_name=key_name, _app=_app, **kw)

        if not key_name:
            key_name = self.key_from(**kw)

    @classmethod
    def key_from(cls, **kw):
        if hasattr(cls, 'key_template'):
            try:
                return cls.key_template % kw
            except KeyError:
                logging.warn(u'Automatic key_name generation failed: %s <- %s',
                              cls.key_template,
                              kw)
                return None

class Account (BaseModel):
    user = db.UserProperty(required=True)
    email = db.EmailProperty()

    key_template = "account/%(user)s"
2

你可以让所有创建 Account 模型的过程都通过一个简单的工厂函数来完成(可以把这个类的名字改成 _Account,这样其他项目中的程序员就能明白这个类是私有的,不应该直接使用):

def make_account(key_name=None, **k):
    if key_name is None:
        raise ValueError('Must specify key_name for account!')
    return _Account(key_name=key_name, **k)

你也可以更复杂一点,把这个过程放在 Account 类的一个 classmethod 里(重写这个类的 __init__ 方法,加一些检查,确保不会被其他地方意外调用),等等,但核心思想就是:“在你的应用程序代码中处理这个问题”。

撰写回答