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 用于区分不同数据视图(如软删除、发布状态)
相关推荐
乌暮5 小时前
数据库--JDBC编程
java·数据库·学习
CodeCraft Studio5 小时前
FastReport VCL发布2026.1版本:全面支持RAD Studio 13,PDF输出功能显著增强
数据库·pdf·rad studio·fastreport·报表设计器·报表开发工具·vcl
Elias不吃糖6 小时前
Qt 6以上版本都试用 连接 MySQL 数据库全流程(CMake 环境)
数据库·qt·mysql
不是二师兄的八戒6 小时前
MySQL 中 HAVING 子句的深度解析与实战指南
数据库·mysql
l1t6 小时前
Duckdb rusty_sheet插件使用心得
数据库·sql·lua·duckdb·rusty_sheet
asdfsdgss6 小时前
PostgreSQL 教程:json 与 jsonb 的数据验证机制差异及实战选择
数据库·postgresql·json
座山雕~6 小时前
MYSQL-超全基础以及用法--仅个人的速记笔记(1)
数据库·mysql
喜欢读源码的小白6 小时前
Spring Boot+MyBatis实现无限层级组织架构设计|邻接表vs闭包表性能对比|树形结构数据存储方案
java·数据库·组织结构·树级层级·无线层级