首先介绍一下 manager 的使用场景,比如我们有一些表级别的,需要重复使用的功能,都可以使用 manager 来实现。

比如我们在前面的笔记中介绍的 model 的 create()、update() 等方法,Blog.objects.create() 中前面的 objects 就是一种 manager,不过这是系统给我们定义的。

那么我们也可以自己通过 manager 的方式来定义一些通用的函数方便我们在系统中使用。

1.定义Manager

2.使用manager

3.通过 manager 更改原始的 QuerySet

1、定义 manager

定义的方式为创建一个继承 models.Manager 的类,定义所需要的函数,然后在 model 里定义 objects 指向这个 Manager 即可:

class BookManager(modls.Manager):
def test_func(self, *args, **kwargs):
# 执行一些操作
return class Book(models.Model): objects = BookManager()

2、使用 manager

假设我们想实现这样一个功能,通过输入一个 keyword,返回所有 name 字段包含 keyword 的数据的总数。

不使用 manager 的话,我们大概每次都会这样来操作:

keyword = "python"
count = Book.objects.filter(name__icontains=keyword)

如果是使用 manager 来实现,则可以先定义这个函数:

class BookManager(models.Manager):
def contain_keyword_count(self, keyword):
return self.filter(name__icontains=keyword).count() class Book(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() objects = BookManager()

那么通过 Manager 来操作便是:

keyword = "python"
count = Book.objects.contain_keyword_count(keyword)

注意,这里指向 BookManager 的变量,我们与系统默认的 objects 保持了一致,我们可以定义为其他名称,不过调用的时候,需要改成其他的形式即可,比如:

class Book(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() book_objects = BookManager Book.book_objects.contain_keyword_count(keyword)

3、通过 manager 更改原始的 QuerySet

有一些底层的 QuerySet 的函数我们也可以通过 manager 的形式来继承修改,比如 get_queryset(),其他的比如 filter()、exclude()、all() 在底层都会调用这个函数。

现在我们来通过 manager 改写这个函数:

class BookManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(name__icontains="python") class Book(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() objects = models.Manager()
book_objects = BookManager()

然后当我们调用下面的:

Book.objects.all()
Book.book_objects.all()

则会是两个结果,第一个返回的是原始的 all() 的结果,第二条则是我们定义了经过筛选的结果。

注意:book_objects 和原来的 objects 一样,可以在原来的基础上进行其他的筛选操作,比如:

Book.book_objects.filter(tagline='xxx')

以上只是简单介绍了 manager 的使用方法,我们可以往 manager 的函数里添加更多复杂的功能函数,这个可以根据需要添加。

参考自:https://zhuanlan.zhihu.com/p/510888239

最新文章

  1. 你真的会玩SQL吗?EXISTS和IN之间的区别
  2. python UnicodeDecodeError: 'ascii' codec can't decode byte 0xa6 in position 907: ordinal not in range(128)
  3. Java泛型 E、T、K、V、N
  4. Mac OS 文件、文件夹重命名的方法
  5. 第一个Struts2程序
  6. The difference between Union & Union All in SQL Server/pOSTGRESQL
  7. Xshell连接本地 Virtualbo Ubuntu
  8. 获取Skype用户IP地址
  9. php解决json_encode输出GB2312中文问题 (数组)
  10. 前端之旅HTML与CSS篇之a便签中放入其他块元素会撑大高度的原因
  11. PHP 文件下载 浅析
  12. Git使用全解
  13. 函数, arguments对象, eval,静态成员和实例成员
  14. git中提交了想要忽略的文件,如何在删除
  15. Linux dmidecode 命令
  16. 2017-2018-2 20155224『网络对抗技术』Exp5:MSF基础应用
  17. Android 数据存储04之Content Provider
  18. windos或linux中 which命令 查看当前要执行的命令所在的路径
  19. JAVA StringUtils需要导入的包
  20. java代码---------实现布尔型的功能,是否执行下一步的关键

热门文章

  1. element的表格组件label宽度设置
  2. 看了这本基础教程的书籍你还担心你的python学不好吗?
  3. vscode自定义工作目录
  4. express的使用:web开发(四)
  5. Selenium私房菜系列7 -- 深入了解Selenium RC工作原理(2)【II】
  6. Ubuntu安装微信/企业微信
  7. Pytorch实战学习(八):基础RNN
  8. 26_自定义Loader
  9. [已解决]Android studio连接远程MySQL问题解决
  10. MyBatis_08(MyBatis缓存)