Как я могу решить, какую декларативную модель создать, основываясь на информации строки - PullRequest
1 голос
/ 21 июня 2011

Я создаю веб-приложение с дополнительным логином на Facebook. Пользователи, созданные с помощью API Facebook, обрабатываются по-разному в нескольких точках моего приложения. Я хочу инкапсулировать эти различия в подкласс 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 Ответ

1 голос
/ 29 июня 2011

Общая идея заключается в том, чтобы хранить имя класса модели в виде метаданных в каждой строке, а при создании экземпляра объекта сделать что-то вроде:

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

Чтобы сделать это в SQLAlchemy, вы можете посмотреть наделая Person базовым классом для чего-то вроде BasicPerson и FacebookPerson, а в Person. init () используйте метаданные для инициализации в соответствующем подклассе.

Например, идея будет заключаться в том, что при возвращении этого запроса пользователь будет инициализирован соответствующим подклассом:

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

Возможно, вам потребуется немного изменить эту концепцию для SQLAlchemy.(Я давно этим не пользовался), но это общая идея.

Или вы можете сделать что-то вроде сохранения метаданных в файле cookie с помощью user_id, а затем, когда они снова войдут в систему, использовать метаданные для передачи соответствующего класса в запрос пользователя:

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

Если вы хотите, чтобы это было общим, чтобы метаданные имели смысл для клиентов, не являющихся Python, вместо того, чтобы хранить имя класса модели, сохраните «object_type» модели и в каждой клиентской библиотеке есть что-то, что отображает object_types в классы.

...