引出重写的原因,我们是通过软删除的方式来删除数据的(即通过status标识来确定数据是否作废)
那么这样的话,我们每一次查询的时候都要写上条件status=1很繁琐。我们可以重写filter_by方法
如上图所示我们现在使用的查询方式并不是SQLAlchemy原生的查询方式,而是flask_sqlalchemy(是对原生SQLAlchemy的一个封装),是因为flask觉得原生的SQLAlchemy不是很方便,就以原生的为基础自己封装了一个flask_sqlalchemy实现了它自己的一些更加方便的查询。所以说上面的query对象是flask_sqlalchemy下面的一个对象。
下面我们flask_sqlalchemy查看源码
在__init__文件的407行有一个BaseQuery
可以看出是继承了orm.Query,这个就是原生SQLAlchemy包里面的一个对象。我们可以看到在BaseQuery下面是没有实现filter_by方法的。下面我们在看一下orm.Query的源码
而在这个文件的1559行就找到了filter_by
可以看到他接收一组参数**kwargs,这个参数就是我们下图传入进来的键值对。kwargs是一个字典!!!
然后在filter_by内部进行了下图源码的处理(我们这里不用管)
如果说我们只需要自己实现filter_by,然后在filter_by的内部加上status=1,最后在调用基类的filter_by方法,就可以完成我们的覆盖改写。
下面开始敲代码啦:
首先导入flask_sqlalchemy的BaseQuery
上图只是仅仅实现我们自己的逻辑了。我们还需要完成filter_by原有的逻辑。
调用基类下面的filter_by方法:
在传入字典的时候我们必须要对字典进行解包所以要传入两个*号
可以看到基类里面是有return的,所以我们要是不return就会有问题,我们需要return一下
现在我们就完成了自定义的Query,但是还没有替换原来的BaseQuery,就要去看一下源码。flask_sqlalchemy给了我们一个替换他原有BaseQuery的机会。这个机会就在flask_sqlalchemy这个他实例化的地方。下面我们在看一次源码:
点进去看到下图:
可以看到在她的构造函数里面是允许传入一个自己的BaseQuery的
这样我们就用自己定义的Query替代了flask_sqlalchemy的BaseQuery
上图就完成了重写flask_sqlalchemy的filter_by方法
所以当我们再调用query对象下面的filter_by方法的时候,就不是调用原来BaseQuery下面的filter_by了,而是调用我们自己改写的这个filter_by。
在替换完成之后我们所有的filter_by中都不需要传入status=1了。