django 的 manager 是继承 models.manager 的类实例,用于集中封装数据访问逻辑;需通过 objects = yourmanager() 替换默认管理器,若需全量查询须额外定义 all_objects;manager 方法应返回 queryset 以支持链式调用,复杂逻辑宜基于自定义 queryset 实现。

为什么不能直接在 Model 类里写查询逻辑
把 filter()、exclude() 这类查询硬写在视图或业务代码里,会导致重复、难测试、改起来牵一发而动全身。Django 的 Manager 就是为把数据访问逻辑集中封装而生的——但它不是装饰器,也不是 mixin,而是一个继承自 models.Manager 的类实例,挂载在模型上后,所有 .objects 调用都会走它。
如何定义并注册一个基础自定义 Manager
最简方式是继承 models.Manager,重写 get_queryset() 方法,然后在模型中用 objects = YourManager() 替换默认管理器:
class PublishedManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(status='published')
<p>class Article(models.Model):
title = models.CharField(max_length=200)
status = models.CharField(max_length=20, choices=[('draft', 'Draft'), ('published', 'Published')])
objects = PublishedManager() # ← 关键:替换默认 manager
</p>
这样 Article.objects.all() 就只返回已发布的文章。注意:一旦覆盖 objects,默认 manager 就没了,如果还需要全量查询,得额外暴露一个 manager,比如 all_objects = models.Manager()。
何时该用 Manager 方法而不是 QuerySet 方法
Manager 方法适合“入口级”操作,比如 Article.objects.published() 或 Article.objects.by_author(user);但如果你需要链式调用(如 .filter().exclude().order_by()),必须让方法返回 QuerySet,且最好基于自定义 QuerySet 类,否则会丢失链式能力。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
-
Manager方法返回QuerySet才能继续链式调用 - 直接在
Manager里写filter()会切断链式,应委托给自定义QuerySet - 想支持
Article.objects.published().by_tag('python'),就得先定义ArticleQuerySet,再在Manager中返回它
常见错误是把复杂过滤逻辑全塞进 Manager 方法里,结果发现没法组合、难复用、单元测试写起来费劲。
多 Manager 共存时的命名和覆盖风险
Django 允许一个模型有多个 manager,比如 objects、published、drafts,但要注意:
- 只有第一个 manager(按代码顺序)被 Django 自动设为
_default_manager,影响Model._meta.get_fields()、admin 列表、select_related()等隐式行为 - 别名 manager 如
published = PublishedManager()不会自动继承get_queryset()以外的方法,除非你显式实现 - 如果用了
objects = models.Manager()+published = PublishedManager(),记得确认 admin 是否仍用objects,否则后台可能看不到草稿
真正容易被忽略的是:manager 的 get_queryset() 在 model 实例化前就执行,所以不能依赖 instance 属性或未保存字段;所有逻辑必须基于数据库字段或可序列化的参数。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










