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 用于区分不同数据视图(如软删除、发布状态)
相关推荐
曹牧3 小时前
Oracle:前缀匹配之REGEXP_LIKE
数据库·oracle
暴躁小师兄数据学院5 小时前
【AI大数据工程师特训笔记】第05讲:关联查询
数据库·sql·oracle
倔强的石头_6 小时前
《Kingbase护城河》——跨平台环境下的数据库联调实战
数据库
lzhdim6 小时前
SQL 入门 17:MySQL 数据类型:从字符串到 JSON 的全面解析
数据库·sql·mysql·json
杨云龙UP6 小时前
Oracle RAC / ODA 生产环境指定 PDB 启动 SOP
linux·运维·数据库·oracle
kingwebo'sZone6 小时前
在Cent上安装Mysql 8.0的遇到的问题和解决办法
数据库·mysql·adb
幽络源小助理6 小时前
最新知识付费系统网站源码 PC+H5双端 附安装教程 – 幽络源源码网
大数据·数据库
小白考证进阶中7 小时前
Oracle OCP证书报考&考试全指南
数据库·oracle·oracle ocp·ocp认证·oracle认证·甲骨文认证·oracle ocp题库
Leon-Ning Liu8 小时前
【真实经验分享】 ORA-600 [qesmaGetTblSeg1]
数据库·oracle
与数据交流的路上8 小时前
MySQL 优化 -- 相关
数据库·mysql