Django项目中规避自定义Manager执行特定查询的方法
在Django中绕过自定义Manager的get_queryset()获取全部记录
我太懂这种场景了——项目里的自定义管理器帮你默认过滤掉了不可见的记录,但突然遇到某个特殊需求必须拿到所有数据,改遍所有代码又不现实。给你几个实用的解决方案,按推荐程度排序:
方案1:新增一个原生管理器到模型(最推荐)
直接在MyModel里加一个使用原生models.Manager的属性,专门用来获取全部记录。改动极小,完全不影响原有逻辑:
class MyModel(models.Model): # 保留原来的自定义管理器,维持默认过滤逻辑 objects = MyModelManager() # 新增原生管理器,用于获取所有记录(包括is_visible=False的) all_objects = models.Manager()
之后在需要的场景里,直接用MyModel.all_objects.all()就能拿到全部数据,平时还是用MyModel.objects.all()走默认过滤,完美区分两种场景,其他开发者看代码也一目了然。
方案2:直接使用模型的_base_manager
Django每个模型都自带一个_base_manager,这是框架内部使用的基础管理器,不会应用你自定义的get_queryset()过滤逻辑。你可以直接调用它:
# 获取所有MyModel记录,绕过自定义管理器的过滤 MyModel._base_manager.all()
不过要注意:官方文档提示尽量避免直接使用_base_manager,除非你明确知道自己在做什么——它不会考虑模型Meta里的default_manager设置,也不会处理一些自定义的模型逻辑,但在你的场景里,这恰恰是你需要的。如果只是临时用几次,这个方法很方便,不用改任何模型代码。
方案3:给自定义管理器添加一个“显示全部”的方法
如果希望语义更清晰,可以在你的MyModelManager里加一个方法,专门返回包含隐藏记录的查询集:
class MyModelManager(models.Manager): def get_queryset(self): return super().get_queryset().exclude(is_visible=False) def with_hidden(self): # 跳过自定义过滤,返回原生查询集 return super().get_queryset()
之后用MyModel.objects.with_hidden().all()就能拿到全部数据,这个方法的好处是,其他开发者看到with_hidden()就知道这个查询包含了原本被隐藏的记录,可读性很强。
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

