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 Подавам му един критерий (username=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
Вижте коментара ми по-горе за контекстните/локалните сесии на нишки, но може би отговорът от Мигел също е полезен. Не знам нищо за 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