🧩 一、Manager 是什么?
Manager 是 Django ORM 提供的数据库操作接口。
每个模型(Model)默认都有一个管理器 objects,用于执行所有数据库查询。
python
class Article(models.Model):
title = models.CharField(max_length=100)
# 默认存在一个 Manager
Article.objects.all() # 查询所有文章
Article.objects.filter(...) # 过滤
✅ Django 在每个 Model 类中自动添加一个 objects = models.Manager()。
你可以通过它访问 ORM 提供的所有方法(filter(), get(), create(), update(), 等)。
🧠 二、Manager 的主要作用
| 功能 | 示例 |
|---|---|
| 定义默认查询范围 | 限制返回的对象(如只显示已发布内容) |
| 添加自定义查询方法 | 封装复杂查询逻辑 |
| 控制默认行为 | 指定模型默认返回什么数据 |
| 逻辑复用 | 让过滤逻辑集中,不重复写在 view 或 service 里 |
⚙️ 三、定义自定义 Manager
✅ 基本结构
python
from django.db import models
class PublishedManager(models.Manager):
def get_queryset(self):
# 定义默认返回的数据范围
return super().get_queryset().filter(is_published=True)
然后在模型中使用它:
python
class Article(models.Model):
title = models.CharField(max_length=100)
is_published = models.BooleanField(default=False)
# 默认管理器
objects = models.Manager()
# 自定义管理器
published = PublishedManager()
📖 使用效果:
python
Article.objects.all() # 所有文章
Article.published.all() # 只返回已发布的文章
🧩 四、get_queryset() 方法详解
get_queryset() 是 Manager 的核心方法,用来定义默认查询集(QuerySet)。
Django 的所有 ORM 操作最终都是基于这个 QuerySet。
示例:
python
class ActiveUserManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
使用:
python
User.active.all() # 只返回活跃用户
User.objects.all() # 所有用户
🔧 五、添加自定义查询方法
你可以在 Manager 中添加业务逻辑方法。
python
class ArticleManager(models.Manager):
def published(self):
return self.get_queryset().filter(is_published=True)
def recent(self):
return self.get_queryset().order_by('-created_at')[:5]
使用:
python
Article.objects.published() # 只返回发布的文章
Article.objects.published().recent() # 最近5篇已发布文章
💡 六、与自定义 QuerySet 结合使用(推荐做法)
Django 推荐将复杂查询逻辑放入自定义 QuerySet,再让 Manager 使用它。
python
class ArticleQuerySet(models.QuerySet):
def published(self):
return self.filter(is_published=True)
def recent(self):
return self.order_by('-created_at')
然后定义 Manager:
python
class ArticleManager(models.Manager):
def get_queryset(self):
return ArticleQuerySet(self.model, using=self._db)
# 让 Manager 支持链式调用
def published(self):
return self.get_queryset().published()
模型:
python
class Article(models.Model):
title = models.CharField(max_length=100)
is_published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
objects = ArticleManager()
📖 调用:
python
Article.objects.published().recent()
✅ 优点:
- 支持链式调用
- QuerySet 与 Manager 逻辑分层更清晰
- 更容易测试与复用
🧱 七、多个 Manager 的应用场景
你可以为同一个模型定义多个 Manager,用于不同业务场景:
python
class Article(models.Model):
title = models.CharField(max_length=100)
is_published = models.BooleanField(default=False)
objects = models.Manager() # 默认管理器
published = PublishedManager() # 只看发布的
🔐 八、Manager 与默认行为
- Django 的通用视图(如
ListView)默认使用模型的 第一个定义的 Manager。 - 如果你想让某个自定义 Manager 成为默认管理器,只需把它放在第一个位置:
python
class Article(models.Model):
published = PublishedManager() # 默认被使用
objects = models.Manager()
🧰 九、实际应用案例
✅ 示例1:用户权限过滤
python
class UserQuerySet(models.QuerySet):
def active(self):
return self.filter(is_active=True)
def staff(self):
return self.filter(is_staff=True)
class UserManager(models.Manager):
def get_queryset(self):
return UserQuerySet(self.model, using=self._db)
def active(self):
return self.get_queryset().active()
python
User.objects.active().staff()
✅ 示例2:软删除模型
python
class SoftDeleteManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(is_deleted=False)
class Post(models.Model):
title = models.CharField(max_length=100)
is_deleted = models.BooleanField(default=False)
objects = SoftDeleteManager()
all_objects = models.Manager() # 可访问已删除的
🧭 十、Manager 与 signals、admin、views 的结合
在 admin 中使用自定义 Manager:
python
class ArticleAdmin(admin.ModelAdmin):
def get_queryset(self, request):
return Article.published.all()
在 views 中使用:
python
def index(request):
articles = Article.objects.published().recent()
return render(request, 'index.html', {'articles': articles})
✅ 总结表
| 概念 | 作用 |
|---|---|
| Manager | ORM 查询接口,用于操作数据库 |
| get_queryset() | 定义默认查询集 |
| 自定义方法 | 封装业务查询逻辑 |
| 自定义 QuerySet | 支持链式调用、逻辑复用 |
| 多个 Manager | 用于区分不同数据视图(如软删除、发布状态) |