文章目录

  • 一、模型管理器对象
    • 1. 自定义模型管理器对象
    • 2. 自定义模型管理器类
    • 3. 自定义模型管理器类应用
      • 3.1 重写框架的方法
      • 3.2 封装自定义方法
    • 4. 模型管理器对象的`model`属性
  • 二、模型类和模型管理类

在文章【Django入门】——Django中通过模型类实现数据表基本操作中,我们知道通过模型类操作数据表时,一般的语法为模型类.objects.方法名(如:all()get()filter()等)。你是否想过objects到底是什么?

一、模型管理器对象

实际上,objects是所谓的模型管理器对象,Django为每一个模型类都生成了一个objects对象作为其类属性,用于操作模型类对应的数据表。

为了演示方便,我们还以文章【Django入门】——通过模型类查询MySQL数据库基本操作中的项目做案例来演示:

$ python manage.py shell
>>> from booktest.models import BookInfo, HeroInfo
>>> type(BookInfo.objects)
<class 'django.db.models.manager.Manager'>
>>> type(HeroInfo.objects)
<class 'django.db.models.manager.Manager'>

由上述代码运行可知,不管是模型类BookInfo还是HeroInfo,其objects对象都是django.db.models.manager.Manager类的一个对象。

1. 自定义模型管理器对象

既然objects只不过是作为模型类的类属性,且是Manager类的一个对象,那么开发者必然可以自定义模型管理器对象,如下列代码所示:

from django.db import models# Create your models here.
class BookInfo(models.Model):"""图书模型类"""book_title = models.CharField(max_length=20)  # 图书名称book_pub_date = models.DateField()  # 出版日期book_read = models.IntegerField(default=0)  # 阅读量,默认为0book_comment = models.IntegerField(default=0)  # 评论量,默认为0is_delete = models.BooleanField(default=False)  # 软删除标记,默认不删除books = models.manager.Manager()  # 自定义一个管理器对象

如下列代码所示,当开发者为模型类自定义一个管理器对象时,此时用于操作数据表的管理器对象就发生了改变:

$ python manage.py shell
>>> from booktest.models import BookInfo
>>> BookInfo.objects.all()
Traceback (most recent call last):File "<console>", line 1, in <module>
AttributeError: type object 'BookInfo' has no attribute 'objects'
>>> BookInfo.books.all()
<QuerySet [<BookInfo: BookInfo object (1)>, <BookInfo: BookInfo object (2)>, <BookInfo: BookInfo object (3)>, <BookInfo: BookInfo object (4)>]>

2. 自定义模型管理器类

实际上,在模型类中通过models.manager.Manager类来自定义模型管理器对象的意义不大,更加有意义的是自定义模型管理器类,在类中进行个性化操作,然后利用该自定义模型管理器类在模型类中创建对象,便可以达到一些想要的效果(如:重写框架的方式、添加自定义方法等):

from django.db import modelsclass BookInfoManager(models.manager.Manager):  # 1.自定义图书模型管理器类"""图书模型管理器类"""pass# Create your models here.
class BookInfo(models.Model):"""图书模型类"""book_title = models.CharField(max_length=20)  # 图书名称book_pub_date = models.DateField()  # 出版日期book_read = models.IntegerField(default=0)  # 阅读量,默认为0book_comment = models.IntegerField(default=0)  # 评论量,默认为0is_delete = models.BooleanField(default=False)  # 软删除标记,默认不删除objects = BookInfoManager()  # 2.自定义一个BookInfoManager类的对象

下列代码显示,此时BookInfoobjects属性即创建于自定义的模型管理器类:

$ python manage.py shell
>>> from booktest.models import BookInfo
>>> type(BookInfo.objects)
<class 'booktest.models.BookInfoManager'>

3. 自定义模型管理器类应用

那么,自定义模型管理器类究竟可以实现什么功能呢?下面是其可以实现的两大主要功能:

3.1 重写框架的方法

假设现在有这样一个需求:要求通过BookInfo.objects.all()查询出来的记录中,剔除is_delete字段为True即为1的记录。为了演示方便,下面先将BookInfo对应的数据表中id为4的记录的is_delete字段置为1:

mysql> use db4_test3;
Database changed
mysql> select * from booktest_bookinfo;
+----+-----------------+---------------+-----------+--------------+-----------+
| id | book_title      | book_pub_date | book_read | book_comment | is_delete |
+----+-----------------+---------------+-----------+--------------+-----------+
|  1 | 射雕英雄传      | 1980-05-01    |        12 |           34 |         0 |
......
|  4 | 雪山飞狐        | 1987-11-11    |        58 |           24 |         0 |
+----+-----------------+---------------+-----------+--------------+-----------+
4 rows in set (0.00 sec)mysql> update booktest_bookinfo set is_delete=1 where id=4;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from booktest_bookinfo;
+----+-----------------+---------------+-----------+--------------+-----------+
| id | book_title      | book_pub_date | book_read | book_comment | is_delete |
+----+-----------------+---------------+-----------+--------------+-----------+
......
|  4 | 雪山飞狐        | 1987-11-11    |        58 |           24 |         1 |
+----+-----------------+---------------+-----------+--------------+-----------+
4 rows in set (0.00 sec)

那么,实现上述需求的方法可以是:在继承了models.manager.Manager类的自定义模型管理器类中重写all()方法:

from django.db import modelsclass BookInfoManager(models.manager.Manager):"""图书模型管理器类"""# 1.改变查询的结果集def all(self):# 1.1 调用父类的all(),获取所有数据集books = super().all()# 1.2 对数据进行过滤books = books.filter(is_delete=False)# 1.3 返回过滤结果return books

由下述代码可知,通过BookInfo.objects.all()进行查询时,的确剔除了字段is_delete取值为1的记录:

$ python manage.py shell
>>> from booktest.models import BookInfo
>>> type(BookInfo.objects)
<class 'booktest.models.BookInfoManager'>
>>> books = BookInfo.objects.all()
>>> for book in books:
...     print(book.id)
...
1
2
3

3.2 封装自定义方法

在文章【Django入门】——Django中通过模型类实现数据表基本操作中,我们知道:每次通过模型类向其对应数据表中插入数据要经过以下几步:

  • 创建模型类对象;
  • 通过模型类对象.类型=字段值的方式为每一个字段赋值;
  • 调用save()方法将数据插入数据表。

事实上,可以如下所示在自定义模型管理器中封装自定义create_book()方法来实现:

from django.db import modelsclass BookInfoManager(models.manager.Manager):  # 1.自定义图书模型管理器类"""图书模型管理器类"""# 1.重写框架的方法# ......# 2.封装自定义方法:直接操作模型类对应的数据表(增删改查)def create_book(self, book_title, book_pub_date):# 2.1 创建一个图书对象book = BookInfo()book.book_title = book_titlebook.book_pub_date = book_pub_date# 2.2 保存数据进数据库book.save()# 2.3 返回book对象return book

通过下列代码可使用上述自定义的create_book()方法向数据表中插入记录:

>>> from booktest.models import BookInfo
>>> book = BookInfo.objects.create_book('鹿鼎记', '1972-9-1')
>>> book.book_title
'鹿鼎记'
>>> book.book_pub_date
'1972-9-1'

查询数据表可知,记录的确被插入了表中:

mysql> select * from booktest_bookinfo;
+----+-----------------+---------------+-----------+--------------+-----------+
| id | book_title      | book_pub_date | book_read | book_comment | is_delete |
+----+-----------------+---------------+-----------+--------------+-----------+
......
|  5 | 鹿鼎记          | 1972-09-01    |         0 |            0 |         0 |
+----+-----------------+---------------+-----------+--------------+-----------+
5 rows in set (0.00 sec)

实际上,通过模型类对数据表的增删改查的操作都可以像上面一样封装成方法使用。

需要指出的是,models.manager.Manager中封装了一个create()方法,其实现的功能和上述create_book()方法基本一致:

>>> book = BookInfo.objects.create(book_title='白马啸西风', book_pub_date='1961-11-1')
>>> book
<BookInfo: BookInfo object (6)>

只是需要说明的是,调用create()方法传参时必须使用关键字参数传参方式。

mysql> select * from booktest_bookinfo;
+----+-----------------+---------------+-----------+--------------+-----------+
| id | book_title      | book_pub_date | book_read | book_comment | is_delete |
+----+-----------------+---------------+-----------+--------------+-----------+
......
|  6 | 白马啸西风      | 1961-11-01    |         0 |            0 |         0 |
+----+-----------------+---------------+-----------+--------------+-----------+
6 rows in set (0.00 sec)

4. 模型管理器对象的model属性

上述代码的create_book()方法中显式使用模型类BookInfo创建了对象,假如修改了模型类的名字,则需要在这里同步进行修改,十分不方便。

实际上,模型管理器对象都有一个名为model的属性,该属性即代表了模型管理器对象当前所在的模型类。

即下列代码中的book = self.model()等价于book = BookInfo()

class BookInfoManager(models.manager.Manager):"""图书模型管理器类"""# 1.重写框架的方法......# 2.封装自定义方法def create_book(self, book_title, book_pub_date):# 2.1 创建一个图书对象book = self.model()book.book_title = book_titlebook.book_pub_date = book_pub_date# 2.2 保存数据进数据库book.save()# 2.3 返回book对象return book

二、模型类和模型管理类

模型类、模型管理器、模型管理器对象的关系如下图所示:

【Django入门】——模型管理器对象、模型管理器类和模型类相关推荐

  1. ⭐openGauss数据库源码解析系列文章—— 对象权限管理⭐

    在前面文章中介绍过"9.3 角色管理整",本篇我们介绍第9章 安全管理源码解析中"9.4 对象权限管理"的相关精彩内容介绍. 9.4 对象权限管理 权限管理是安 ...

  2. Django 入门项目案例开发(上)

    关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277 获取学习资料和一起探讨问题. Django 入门案例开发(中) http://www.cnblogs.com/focusBI ...

  3. Django框架(16.Django中的模型类管理器以及自定义管理器)

    模型类.objects.all()->objects是一个什么东西呢? 答:objects是Django帮我自动生成的管理器对象,通过这个管理器可以实现对数据的查询. objects是model ...

  4. Django站点管理、视图和URL(管理界面本地化、创建管理员、注册模型类、发布内容到数据库、定义视图、配置URLconf)

    1.Django站点管理 站点: 分为内容发布和公共访问两部分 内容发布的部分由网站的管理员负责查看.添加.修改.删除数据 Django能够根据定义的模型类自动地生成管理模块 使用Django的管理模 ...

  5. Django——admin功能、注册模型类、模型管理类

    Django 初始化后台管理 ​ 当一个 Django 项目第一次使用 admin 后台管理功能时,需要通过两步实现,第一步是本地化操作,第二步创建管理员 本地化 ​ 实现语言和时区本地化,修改 Dj ...

  6. django 1.8 官方文档翻译: 2-5-1 管理器 (初稿)

    Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质. 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html ...

  7. django 1.8 官方文档翻译: 2-5-1 管理器

    管理器 class Manager 管理器是一个接口,数据库查询操作通过它提供给django的模型.django应用的每个模型至少拥有一个 管理器. 管理器类的工作方式在 执行查询文档中阐述,而这篇文 ...

  8. java jvm内存模型_Java(JVM)内存模型– Java中的内存管理

    java jvm内存模型 Understanding JVM Memory Model, Java Memory Management are very important if you want t ...

  9. Django入门,制作在线相册管理

    在线相册管理 步骤 创建项目 配置settings文件 构建模型 创建templates目录,创建静态页面 配置路由 定义view文件 启动项目 gitee源码地址: 步骤 注意:运行代码要确保系统安 ...

最新文章

  1. Android中Messenger进程间通信
  2. 【每日一题】剑指 Offer 10- I. 斐波那契数列
  3. Android 即时通讯开发小结(二)
  4. idea如何连接本地mysql_IDEA如何连接MYSQL
  5. Ubuntu下一个openldapserver部署步骤
  6. Ngui之UI框架的层级处理
  7. Redis中的管道有什么用?
  8. 12C 新特性 | 标量子查询自动转换
  9. Apache Camel,Spring Boot 实现文件复制,转移 (转)
  10. 何先振第2期:Java语言描述与编写第一个程序
  11. 如何手动配置IP地址
  12. 源码搜索引擎,让你找到更适合你的源码
  13. element-ui —— el-tooltip 超出部分显示省略号,鼠标悬浮显示详情
  14. eclipse离线搭建maven项目,配置本地仓库,并创建mybatis项目
  15. 《经济学的思维方式》内容
  16. 计算机勾兑双绝是谁发明,那些跟你说“勾兑酒”是酒精酒的人,都是在不懂装懂...
  17. ffmpeg的中文文档(二)
  18. excel有安全密码,怎么打开
  19. 我的世界1.12.2java下载_我的世界:Minecraft Java版 1.12.2-pre1发布
  20. Currency Trading: Dollar in a Funk as Traders Bet on Slow Rebound

热门文章

  1. WebAssembly在白鹭引擎5.0中的实践
  2. 申宝优配-强者恒强还将继续
  3. 批量安装当前文件夹下的exe文件
  4. linux shell翻译英文脚本
  5. 微信红包业务,为什么采用轮询算法?
  6. 《 最新中国高校毕业生薪资报告 》
  7. hss网元 java_在NB-IoT建构和流程中,作为网元实体的MME和HSS进行了哪些功能方面的升级?...
  8. 关于antd Tree组件修改图标
  9. SAP-FI-查看供应商,客户,总账科目记账明细
  10. CyclicBarrier实现赛马游戏