2011-06-21 13 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映射到類的東西。