Flask-SQLAlchemy. Можете ли вы сделать запрос в рамках модели?

Я создаю фляжное веб-приложение, которое использует Flask-SQLAlchemy, и я также рассматриваю возможность использования Flask-Login для управления сеансами и защиты определенных представлений.

Flask-Login требует определенных методов, которые я считаю полезными для различных частей приложения (в частности, is_authenticated() и is_active(). Однако во всех примерах, которые я видел, эти методы просто возвращают что-то фиксированное. Что, если я хочу сделать запрос Например, если я хочу проверить, действительно ли у этого пользователя есть запись в таблице (я использую LDAP для входа в систему, поэтому хочу, чтобы пользователи могли войти в систему, даже если у них нет записи в таблице, хотя мне нужно посмотреть, есть ли они там).

Но я не знаю, можно ли сделать запрос к самой таблице из класса, который ее определяет? Или я должен разместить эти функции в другом месте (даже если методы необходимы для flask-login в пользовательском классе)?


person penguin    schedule 15.12.2013    source источник
comment
Что произойдет, если вы попробуете self.query.filter(your=criteria, goes=here) одним из ваших методов? ;-)   -  person Sean Vieira    schedule 15.12.2013
comment
@SeanVieira Я передаю ему один критерий (имя пользователя = self.username), но, похоже, ему это не нравится: TypeError: <lambda>() got an unexpected keyword argument 'username'   -  person penguin    schedule 15.12.2013


Ответы (2)


Вы можете. Обычно Session.object_session представляет собой хороший способ получить сеанс и выполнить запрос:

class MyModel(Base):
    __tablename__ = u'model_table'
    id = Column(Integer, primary_key=True)
    # ...

    def my_method(self):
       session = Session.object_session(self)
       qry = session.query(...).filter(...)
       # ...
person van    schedule 15.12.2013
comment
Ах, это выглядит правильно. Я импортировал from sqlalchemy.orm.session import Session, а затем session = Session.object_session(self). Однако тогда сессия выглядит как None. Интересно, что я делаю неправильно? - person penguin; 15.12.2013
comment
Объект (self) уже добавлен в сеанс или загружен из базы данных? Если это совершенно новый экземпляр и он не был добавлен в сеанс (временный; см. Краткое введение в состояния объектов), object_session действительно возвращает None. В этом случае вы всегда можете просто создать новую сессию; но в веб-приложениях часто используются контекстные сеансы. См. Контекстные/локальные сеансы потока для получения дополнительной информации. - person van; 15.12.2013
comment
Ах, так как записи еще нет в базе данных, и я еще не сделал фиксацию, сеанса еще не будет. Как мне создать его внутри класса, оставаясь при этом в рамках спецификации методов, которые мне нужно использовать? Потому что я не думаю, что смогу передать детали привязки в этих методах. - person penguin; 16.12.2013
comment
См. мой комментарий выше о сеансах Contextual/Thread-Local, но, возможно, ответ от Мигеля также будет полезен. Я ничего не знаю о Flask и Flast-SQLAlchemy - person van; 16.12.2013

Flask-Login требует, чтобы вы предоставили пользовательский объект в обратном вызове загрузчика пользователя. Этот пользователь не должен быть подкреплен записью в базе данных, это может быть любой объект, если он реализует необходимые методы, такие как is_authenticated() и is_active().

Из вашего описания мне кажется, что представление пользователя, которое вам нужно, это не то, которое сопоставляется один к одному с пользовательской таблицей в вашей базе данных, поскольку у вас есть действительные пользователи, которых нет в вашей базе данных.

Один подход, который вы можете использовать, состоит в том, чтобы иметь два пользовательских класса, оба из которых реализуют требуемые методы. Назовем их DBUser и LDAPUser. Пока вы разработаете стратегию иметь уникальные идентификаторы для экземпляров двух классов, Flask-Login будет все равно.

Класс DBUser может быть подходящей моделью базы данных, основанной на Flask-SQLAlchemy, с простой реализацией методов is_xxx(). Класс LDAPUser, с другой стороны, может реализовать эти методы, отправляя любые необходимые запросы к базе данных в DBUser.query.

person Miguel    schedule 16.12.2013