2011-06-21 14 views
1

我正在构建具有可选Facebook登录的Web应用程序。通过Facebook API创建的用户在我的应用程序中的多个点处理方式不同。我想将这些差异封装在覆盖方法的子类Person中。如何根据行信息决定要实例化哪个声明模型

class Person(Model): 
    def get_profile_picture(self): 
     return profile_pictures.url(self.picture) 

class FacebookPerson(Person): 
    def get_profile_picture(self): 
     return 'http:/.../%s.jpg' % self.graph_id 

我想避免讨厌的if self.graph_id,只是查询Person模型,并得到每个用户的合适的对象。

我想到了黑客入侵的metaclass来添加FacebookPerson作为基础。显然我想避免这种巫术。

我正在使用Flask和Flask-SQLAlchemy。

回答

1

的总体思路是将模型的类名作为元数据存储在每一行中,当你实例化对象,这样做:

def query(self): 
    # stuff 
    return model_class(data) 

要在SQLAlchemy中做到这一点,你可能看制作基本类的人是像BasicPerson和FacebookPerson,并在人。 init(),使用元数据初始化到适当的子类。

例如,这个想法会比当此查询返回,用户将被初始化到正确的子类:

user = session.query(Person).filter_by(name='james').first() 

你可能会需要修改这个概念有点为SQLAlchemy的(我的天堂”稍后会用到它),但这是一般想法。

或者,你可以不喜欢存储元数据与USER_ID一个cookie,然后当他们再次登录时,使用元数据的正确类传递给用户查询:

user = session.query(FacebookPerson).filter_by(name='james').first() 

如果您希望这是通用的,以便元数据对非Python客户端有意义,而不是存储模型的类名称,存储模型的“object_type”并在每个客户端库中都有一些将object_types映射到类的东西。