zoukankan      html  css  js  c++  java
  • 重写flask_sqlalchemy的BaseQuery下面的filter_by方法

    前言

    • 引出重写的原因,我们是通过软删除的方式来删除数据的(即通过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方法:上图只是仅仅实现我们自己的逻辑了。我们还需要完成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了。

    附上代码

    class Query(BaseQuery):
        def filter_by(self, **kwargs):
            if 'status' not in kwargs.keys():
                kwargs['status'] = 1
            return super(Query, self).filter_by(**kwargs)
        
        # 以下方法是重写了BaseQuery类下面的方法,目的是抛出我们自定义的异常
        def get_or_404(self, ident, description=None):
            """返回指定主键对应的行,如不存在,抛出自定义异常类"""
    
            rv = self.get(ident)
            if rv is None:
                raise ValError(msg='未查询到该数据')
            return rv
    
        def first_or_404(self, description=None):
            """返回查询的第一个结果,如果未查到,抛出自定义异常类"""
    
            rv = self.first()
            if rv is None:
                raise ValError(msg='未查询到该数据')
            return rv
    
    
    db = SQLAlchemy(query_class=Query)
    
  • 相关阅读:
    hibernate03增删改查
    hibernate02环境的搭建
    hibernate01ORM的引入
    20170623_oracle_优化与体系结构
    20170626_oracle_数据库设计
    logging模块
    hashlib模块
    json和pickle模块
    sys模块
    os模块
  • 原文地址:https://www.cnblogs.com/se7enjean/p/12848656.html
Copyright © 2011-2022 走看看