详解Python的Django框架中Manager方法的使用


Posted in Python onJuly 21, 2015

在语句Book.objects.all()中,objects是一个特殊的属性,需要通过它查询数据库。 在第5章,我们只是简要地说这是模块的manager 。现在是时候深入了解managers是什么和如何使用了。

总之,模块manager是一个对象,Django模块通过它进行数据库查询。 每个Django模块至少有一个manager,你可以创建自定义manager以定制数据库访问。

下面是你创建自定义manager的两个原因: 增加额外的manager方法,和/或修manager返回的初始QuerySet。
增加额外的Manager方法

增加额外的manager方法是为模块添加表级功能的首选办法。

例如,我们为Book模型定义了一个title_count()方法,它需要一个关键字,返回包含这个关键字的书的数量。 (这个例子有点牵强,不过它可以说明managers如何工作。)

# models.py

from django.db import models

# ... Author and Publisher models here ...

**class BookManager(models.Manager):**
  **def title_count(self, keyword):**
    **return self.filter(title__icontains=keyword).count()**

class Book(models.Model):
  title = models.CharField(max_length=100)
  authors = models.ManyToManyField(Author)
  publisher = models.ForeignKey(Publisher)
  publication_date = models.DateField()
  num_pages = models.IntegerField(blank=True, null=True)
  **objects = BookManager()**

  def __unicode__(self):
    return self.title

有了这个manager,我们现在可以这样做:

>>> Book.objects.title_count('django')
4
>>> Book.objects.title_count('python')
18

下面是编码该注意的一些地方:

  •     我们建立了一个BookManager类,它继承了django.db.models.Manager。这个类只有一个title_count()方法,用来做统计。 注意,这个方法使用了self.filter(),此处self指manager本身。
  •     我们把BookManager()赋值给模型的objects属性。 它将取代模型的默认manager(objects)如果我们没有特别定义,它将会被自动创建。 我们把它命名为objects,这是为了与自动创建的manager保持一致。

为什么我们要添加一个title_count()方法呢?是为了将经常使用的查询进行封装,这样我们就不必重复编码了。
修改初始Manager QuerySets

manager的基本QuerySet返回系统中的所有对象。 例如,`` Book.objects.all()`` 返回数据库book中的所有书本。

我们可以通过覆盖Manager.get_query_set()方法来重写manager的基本QuerySet。 get_query_set()按照你的要求返回一个QuerySet。

例如,下面的模型有* 两个* manager。一个返回所有对像,另一个只返回作者是Roald Dahl的书。

from django.db import models

**# First, define the Manager subclass.**
**class DahlBookManager(models.Manager):**
  **def get_query_set(self):**
    **return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')**

**# Then hook it into the Book model explicitly.**
class Book(models.Model):
  title = models.CharField(max_length=100)
  author = models.CharField(max_length=50)
  # ...

  **objects = models.Manager() # The default manager.**
  **dahl_objects = DahlBookManager() # The Dahl-specific manager.**

在这个示例模型中,Book.objects.all()返回了数据库中的所有书本,而Book.dahl_objects.all()只返回了一本. 注意我们明确地将objects设置成manager的实例,因为如果我们不这么做,那么唯一可用的manager就将是dah1_objects。

当然,由于get_query_set()返回的是一个QuerySet对象,所以我们可以使用filter(),exclude()和其他一切QuerySet的方法。 像这些语法都是正确的:

Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()

这个例子也指出了其他有趣的技术: 在同一个模型中使用多个manager。 只要你愿意,你可以为你的模型添加多个manager()实例。 这是一个为模型添加通用滤器的简单方法。

例如:

class MaleManager(models.Manager):
  def get_query_set(self):
    return super(MaleManager, self).get_query_set().filter(sex='M')

class FemaleManager(models.Manager):
  def get_query_set(self):
    return super(FemaleManager, self).get_query_set().filter(sex='F')

class Person(models.Model):
  first_name = models.CharField(max_length=50)
  last_name = models.CharField(max_length=50)
  sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
  people = models.Manager()
  men = MaleManager()
  women = FemaleManager()

这个例子允许你执行`` Person.men.all()`` ,`` Person.women.all()`` ,`` Person.people.all()`` 查询,生成你想要的结果。

如果你使用自定义的Manager对象,请注意,Django遇到的第一个Manager(以它在模型中被定义的位置为准)会有一个特殊状态。 Django将会把第一个Manager 定义为默认Manager ,Django的许多部分(但是不包括admin应用)将会明确地为模型使用这个manager。 结论是,你应该小心地选择你的默认manager。因为覆盖get_query_set() 了,你可能接受到一个无用的返回对像,你必须避免这种情况。

Python 相关文章推荐
举例讲解Python程序与系统shell交互的方式
Apr 09 Python
谈谈Python进行验证码识别的一些想法
Jan 25 Python
浅谈Python基础之I/O模型
May 11 Python
Python正则表达式分组概念与用法详解
Jun 24 Python
python实现二叉树的遍历
Dec 11 Python
Python爬虫实现爬取百度百科词条功能实例
Apr 05 Python
python使用OpenCV模块实现图像的融合示例代码
Apr 10 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
django admin管理工具自定义时间区间筛选器DateRangeFilter介绍
May 19 Python
Python 在局部变量域中执行代码
Aug 07 Python
Python图片处理之图片裁剪教程
May 27 Python
利用Python将list列表写入文件并读取的方法汇总
Mar 25 Python
通过数据库对Django进行删除字段和删除模型的操作
Jul 21 #Python
通过数据库向Django模型添加字段的示例
Jul 21 #Python
Django的数据模型访问多对多键值的方法
Jul 21 #Python
举例讲解Django中数据模型访问外键值的方法
Jul 21 #Python
编写自定义的Django模板加载器的简单示例
Jul 21 #Python
详解Python的Django框架中inclusion_tag的使用
Jul 21 #Python
剖析Django中模版标签的解析与参数传递
Jul 21 #Python
You might like
php学习之数据类型之间的转换介绍
2011/06/09 PHP
PHP获取音频文件的相关信息
2015/06/22 PHP
解析PHP之提取多维数组指定列的方法
2017/01/03 PHP
thinkphp5+layui实现的分页样式示例
2019/10/08 PHP
NodeJS的模块写法入门(实例代码)
2012/03/07 NodeJs
js单例模式详解实例
2013/11/21 Javascript
深入理解JS中的变量及作用域、undefined与null
2014/03/04 Javascript
详解AngularJS中$http缓存以及处理多个$http请求的方法
2016/02/06 Javascript
Bootstrap每天必学之导航条(二)
2016/03/01 Javascript
原生ajax处理json格式数据的实例代码
2016/12/25 Javascript
微信小程序 动态传参实例详解
2017/04/27 Javascript
设置cookie指定时间失效(实例代码)
2017/05/28 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
使用Vue-cli3.0创建的项目 如何发布npm包
2019/10/10 Javascript
浅谈Vue为什么不能检测数组变动
2019/10/14 Javascript
javascript实现京东登录显示隐藏密码
2020/08/02 Javascript
python轻松查到删除自己的微信好友
2016/01/10 Python
Python操作配置文件ini的三种方法讲解
2019/02/22 Python
python 计算一个字符串中所有数字的和实例
2019/06/11 Python
python async with和async for的使用
2019/06/20 Python
分享8点超级有用的Python编程建议(推荐)
2019/10/13 Python
Python监控服务器实用工具psutil使用解析
2019/12/19 Python
Coach澳大利亚官方网站:美国著名时尚奢侈品牌
2017/05/24 全球购物
size?德国官方网站:英国伦敦的球鞋精品店
2018/03/17 全球购物
荷兰游戏商店:Allyouplay
2019/03/16 全球购物
Currentbody美国/加拿大:美容仪专家
2020/03/09 全球购物
奥地利手表、香水、化妆品和珠宝购物网站:Brasty.at
2021/01/17 全球购物
介绍一下UNIX启动过程
2013/11/14 面试题
乐观自信演讲稿范文
2014/05/21 职场文书
社区平安建设汇报材料
2014/08/14 职场文书
表扬信格式模板
2015/05/05 职场文书
2016年清明节网上祭英烈活动总结
2016/04/01 职场文书
创业计划书之o2o水果店
2019/08/30 职场文书
JavaScript canvas实现流星特效
2021/05/20 Javascript
python实现对doc、txt、xls等文档的读写操作
2022/04/02 Python
python index() 与 rindex() 方法的使用示例详解
2022/12/24 Python