【后端】【django】【进阶】自定义管理器——封装常用查询

ops/2025/3/28 7:46:27/

1. 自定义管理器的作用

Django 的 models.Manager 允许自定义查询逻辑,让你更方便地封装常用查询,提高代码复用性。

在你的示例中:

  • objects = models.Manager() 是 Django 默认的管理器,返回所有数据。
  • published = PublishedManager() 是自定义的管理器,只返回已发布的文章is_published=True)。
  • 这样可以通过 Article.published.all() 快速获取已发布的文章,而不影响 Article.objects.all() 返回所有文章。

2. 代码解析

class PublishedManager(models.Manager):def get_queryset(self):return super().get_queryset().filter(is_published=True)

(1)get_queryset() 方法

  • 作用:重写 get_queryset(),修改默认查询集(QuerySet)。
  • 原理super().get_queryset() 获取原始 QuerySet,然后 .filter(is_published=True) 让它只返回 is_published=True 的数据。

3. 使用示例

# 创建文章
Article.objects.create(title="草稿文章", content="这是一篇草稿", is_published=False)
Article.objects.create(title="已发布文章", content="这是一篇已发布的文章", is_published=True)# 查询所有文章
print(Article.objects.all())  
# 输出: <QuerySet [<Article: 草稿文章>, <Article: 已发布文章>]># 只查询已发布的文章
print(Article.published.all())  
# 输出: <QuerySet [<Article: 已发布文章>]>
  • Article.objects.all() 返回所有文章。
  • Article.published.all() 自动过滤掉未发布的文章

4. 其他常见用法

(1)添加自定义方法

可以在 PublishedManager 里添加更多自定义方法,比如查询最近发布的文章:

class PublishedManager(models.Manager):def get_queryset(self):return super().get_queryset().filter(is_published=True)def recent(self, days=7):from django.utils.timezone import nowreturn self.get_queryset().filter(created_at__gte=now() - timedelta(days=days))class Article(models.Model):title = models.CharField(max_length=100)content = models.TextField()is_published = models.BooleanField(default=False)created_at = models.DateTimeField(auto_now_add=True)objects = models.Manager()  # 默认管理器published = PublishedManager()  # 只返回已发布的文章
使用方法
# 查询最近 7 天发布的文章
Article.published.recent()

(2)防止 objects 被覆盖

如果 objects 只使用 PublishedManager,就无法查询未发布的文章

class Article(models.Model):title = models.CharField(max_length=100)content = models.TextField()is_published = models.BooleanField(default=False)objects = PublishedManager()  # 这样 `objects.all()` 也只返回已发布的文章

如果要查询所有文章(包括未发布的),最好保留 objects = models.Manager(),这样:

  • Article.objects.all() 获取所有文章
  • Article.published.all() 只获取已发布的文章

5. 总结

功能默认管理器 objects自定义管理器 published
返回所有数据Article.objects.all()
只返回已发布数据Article.published.all()
可以扩展更多方法Article.published.recent()

💡 适用于哪些场景?

  • 需要频繁筛选某些特定数据(如已发布文章、活跃用户)。
  • 让查询更语义化,避免重复 filter()
  • 避免 objects 被污染,保留所有数据的访问能力

http://www.ppmy.cn/ops/167552.html

相关文章

Vue3生态工具:Volar语言服务与Unplugin自动化导入配置

Vue3生态工具&#xff1a;Volar语言服务与Unplugin自动化导入配置 在Vue.js生态系统中&#xff0c;Volar和Unplugin是两个备受关注的工具&#xff0c;它们分别为开发者提供了语言服务和自动化导入配置的便利。本文将介绍Volar语言服务和Unplugin自动化导入配置的原理、用法&…

安防监控视频平台EasyNVR级联视频上云系统EasyNVS出现“Login error”报错的原因排查

EasyNVR安防视频云平台是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif协议接入的安防监控流媒体视频云平台。平台具备视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视频能力&#xff0c;能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、W…

Grid 布局实现三栏布局

使用 CSS Grid 布局实现三栏布局(左右固定 100px,中间自适应)的核心原理是通过网格模板精确控制列宽分配。以下是具体实现方法及优化技巧: 一、基础实现 ​父容器设置 为外层容器添加 display: grid 使其成为网格容器,并通过 grid-template-columns 定义列宽 css .contain…

git推送代码相关学习——(一)

推荐去阅读一下廖老师的git相关的教程https://liaoxuefeng.com/books/git/introduction/index.html 这个系列就来学习一下git操作。 第一步&#xff0c;新建项目 去github中新建一个项目&#xff0c;然后依据项目来进行本地的开发工作。 第二步&#xff0c;拉取项目 git c…

【动态规划篇】91. 解码方法

91. 解码方法 题目链接&#xff1a; 91. 解码方法 题目叙述&#xff1a; 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; “1” -> ‘A’ “2” -> ‘B’ … “25” -> ‘Y’ “26” -> ‘Z’ 然而&#xff0c;在解码已编码的消息时&#xff0c;你…

DeDeCMS靶场攻略

文件管理器 点击模块&#xff0c;选择上传文件 在电脑中新建2.php <?php phpinfo();?> 访问2.php,验证是否成功 修改模板文件 在模块中找到index.htm 在index.htm加上<?php phpinfo();?> 点击生成->更新主页HTML,将index.html改为index.php 访问index.ph…

20250319在荣品的PRO-RK3566开发板的buildroot系统下使用集成的QT应用调试串口UART3

stty -F /dev/ttyS3 115200 -echo cat /dev/ttyS3 & echo serialdata > /dev/ttyS3 20250319在荣品的PRO-RK3566开发板的buildroot系统下使用集成的QT应用调试串口UART3 2025/3/19 14:17 缘起&#xff1a;在荣品的PRO-RK3566开发板的buildroot系统下&#xff0c;在命令…

无需编程!快速实现WinCC远程监控与报警

2. 无需编程&#xff01;快速实现WinCC远程监控与报警 痛点分析&#xff1a;企业缺乏专业编程人员&#xff0c;难以开发复杂监控系统。 解决方案&#xff1a;利用OPC560的即插即用功能&#xff0c;3步完成配置。 技术步骤&#xff1a; 连接OPC560至WinCC电脑&#xff1b; 通…