9.4 重写filter_by

由于我们的删除操作都是逻辑删除,所以在查询的时候应该默认查询status=1的记录(即未删除的记录),但是如果在每一个filter_by里都这么写,就太麻烦了,我们的思路是重写默认的filter_by函数,加上status=1的限制条件。

那么我们就需要先了解原来SQLAlchemy的继承关系 Flask的SQLAlchemy中有一个BaseQuery,BaseQuery继承了orm.Query(原SQLAlchemy的类),这里面有filter_by函数;也就是说BaseQuery通过继承orm.Query拥有了filter_by的能力

flask_sqlalchemy

...
...
class SQLAlchemy(object):
    Query = None

    def __init__(self, app=None, use_native_unicode=True, session_options=None,
                 metadata=None, query_class=BaseQuery, model_class=Model):
...
...

class BaseQuery(orm.Query):
...
...

orm.Query

    def filter_by(self, **kwargs):
        # for循环拼接关键字参数查询条件
        clauses = [_entity_descriptor(self._joinpoint_zero(), key) == value
                   for key, value in kwargs.items()]
        return self.filter(sql.and_(*clauses))

所以如果我们要重写filter_by,需要自己编写子类,继承BaseQuery,重写filter_by函数,将status=1加入到kwargs

class Query(BaseQuery):

    def filter_by(self, **kwargs):
        if 'status' not in kwargs:
            kwargs['status'] = 1
        return super(Query, self).filter_by(**kwargs)

最后,Flask的SQLAlchemy给了我们一种方法,让我们应用自己的Query类,即在实例化的时候传入关键字参数query_class

db = SQLAlchemy(query_class=Query)

Last updated