django model Manager

🧩 一、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 用于区分不同数据视图(如软删除、发布状态)
相关推荐
Nerd Nirvana6 分钟前
数据库模型全景:从原理到实践的系统性指南
数据库·oracle·电力行业
SelectDB8 分钟前
从 Greenplum 到 Doris:集群缩减 2/3、年省数百万,度小满构建超大规模数据分析平台经验
数据库·数据分析·apache
alonewolf_9915 分钟前
MySQL索引优化实战二:分页、关联查询与Count优化深度解析
数据库·mysql
TDengine (老段)1 小时前
TDengine Python 连接器进阶指南
大数据·数据库·python·物联网·时序数据库·tdengine·涛思数据
赵渝强老师1 小时前
【赵渝强老师】OceanBase的配置文件与配置项
数据库·oceanbase
玖日大大2 小时前
OceanBase SeekDB:AI 原生数据库的技术革命与实践指南
数据库·人工智能·oceanbase
高溪流3 小时前
3.数据库表的基本操作
数据库·mysql
alonewolf_993 小时前
深入剖析MySQL锁机制与MVCC原理:高并发场景下的数据库核心优化
数据库·mysql
一 乐3 小时前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
Codeking__4 小时前
Redis初识——什么是Redis
数据库·redis·mybatis