我正在构建一个具有可选Facebook登录的webapp . 通过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模型并为每个用户获取正确的对象 .
我曾想过攻击元类以添加FacebookPerson作为基础 . 显然我想避免这样的伏都教 .
我正在使用Flask和Flask-SQLAlchemy .
1 回答
一般的想法是将模型的类名存储为每行中的元数据,并在实例化对象时执行以下操作:
要在SQLAlchemy中执行此操作,您可能会将Person设置为BasicPerson和FacebookPerson以及Person中的基类 . init (),使用元数据初始化为正确的子类 .
例如,这个想法将比这个查询返回时,用户将被初始化为正确的子类:
您可能需要为SQLAlchemy稍微修改一下这个概念(我暂时没有使用它),但这是一般的想法 .
或者,您可以使用user_id将元数据存储在cookie中,然后在再次登录时使用元数据将正确的类传递给用户查询:
如果您希望这是通用的,以便metatdata对非Python客户端有意义,而不是存储模型的类名,则存储模型的“object_type”并在每个客户端库中有一些将object_types映射到类的东西 .