22

我有一个带有字段 is_deleted 的模型,现在除了传递给 .filter 和 .filter_by 的任何过滤参数之外,我希望该模型的所有形式的查询始终按 is_deleted=False 过滤。

在 Django 中,我通常会覆盖管理器并添加我自己的过滤器,但我需要 SQLAlchemy 的帮助。

更新:

我最终做了以下事情:

class CustomQuery(Query):
    def __new__(cls, *args, **kwargs):
        if args and hasattr(args[0][0], "is_deleted"):
            return Query(*args, **kwargs).filter_by(is_deleted=False)
        else:
            return object.__new__(cls)
session = scoped_session(sessionmaker(query_cls=CustomQuery))

它可以工作,但如果我以后有更多字段,我想我将不得不添加更多条件,必须有一种方法可以在模型级别上做到这一点。

4

1 回答 1

3

这是一个非常古老的问题,所以我确信 OP 解决了他们的问题,但由于它仍未得到解答(在 2021 年),这就是我们如何将自定义查询类应用于所有模型:

  1. 如上定义自定义查询
class CustomQuery(Query): ...
  1. 然后将此查询类设置为基本模型类的查询属性:
class BaseModel(Model):
    __abstract__ = True
    query_class = CustomQuery
    ...

那么任何实现 BaseModel 的模型显然都会继承这种行为:

class MyModel(BaseModel):
    __tablename__ = 'my_model' 
    ....

注意,在我们的例子中,并不是所有的表都遵循软删除模式(我们不关心每个表的历史)。在这里,您可以实现一个使用默认查询类的单独 BaseModel。

class ImmutableBaseModel(Model):
    __abstract__ = True
    query_class = CustomQuery
    ...

class MutableBaseModel(Model):
    __abstract__ = True

如果您发现自己在这里并且还没有阅读它,请查看 Miguel Grinberg 的这篇关于实现软删除模式随附 repo的优秀博客文章

 

于 2021-03-25T10:02:39.837 回答