添加一些模型引用到现有模型

时间:2011-05-02 11:39:51

标签: python google-app-engine

我创建了一个模块,为我自己的身份验证和用户系统提供服务。它是我在不同应用程序中使用的通用模块。在此模块中,描述了User模型,如下所示:

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)

在我使用此模块的任何单个应用程序中,我想创建一个额外的模型来描述特定于此应用程序的其他字段,如下所示:

 class UserProfile(db.Model):
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

我需要在我新制作的应用程序中将UserProfile模型附加到User模型。如何在不修改所有应用程序通用的模块内的代码的情况下执行此操作?

3 个答案:

答案 0 :(得分:2)

如果我有一个我在多个项目中导入的用户模块,我会将此共享模块视为 base 来构建我的应用程序。

所以你可能有一个baseuser.py模块包含:

class UserModel(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)

然后在每个GAE项目中,您将拥有:

from baseuser import UserModel

class User(UserModel):
    first_name = db.StringProperty()
    last_name = db.StringProperty()
    company = db.StringProperty()

然后,您可以自由扩展每个应用的用户模型,并将所有共享逻辑保存在一个位置。

答案 1 :(得分:1)

因此,在任何一个应用程序中,这可能是一对一的关系。因此,存储引用的位置是任意的。您只需修改UserProfile模型以引用用户:

class UserProfile(db.Model):
        user = db.ReferenceProperty(User)
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

然后,在控制器中:

user = User.filter('email =', email).get()
profile = UserProfile.filter('user =', user).get()

或者,如果您希望引用存在于User对象上但不破坏不支持配置文件的应用程序,则可以执行以下操作:

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)
    profile = db.ReferenceProperty()

这是您在用户上指定弱配置文件参考。它不是必需的,如果你填充它,它不一定是特定的模型。这使您可以选择存储配置文件引用,而不会破坏兼容性。

最后,您可以完全跳过配置文件,只需创建用户对象an Expando

答案 2 :(得分:0)

所有应用程序是否共享数据库?在这种情况下,您不能将UserProfile存储为User模型的字段,因为User并不总是具有关联的配置文件。我会将User设置为UserProfile的一个字段并让它指向那个方式(UserProfile包含一个User),并将UserProfile的user字段编入索引,以便您可以快速查找给定用户的UserProfile。

如果您只对代码重用感兴趣但不共享公共数据库,那么您可以根据应用程序使这些附加字段成为条件。例如:

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)
    if APP_HAS_USER_PROFILES:
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

然后最后三个字段只会出现在某些应用程序中。我相信你也可以从User继承UserProfile,但我不确定当时会发生什么(就数据库而言)。