Django 自定义模型管理器(Manager)及方法
转载自:https://www.cnblogs.com/sui776265233/p/11571418.html
1.自定义管理器(Manager)
在语句Book.objects.all()中,objects是一个特殊的属性,通过它来查询数据库,它就是模型的一个Manager.
每个Django模型至少有一个manager,你可以创建自定义manager以定制数据库的访问.
这里有两个方法创建自定义manager:添加额外的manager;修改manager返回的初始Queryset.
添加额外的manager
增加额外的manager是为模块添加表级功能的首选办法.(至于行级功能,也就是只作用于模型实例对象的函数,则通过自定义模型方法实现).
例如,为Book模型添加一个title_count()的manger方法,它接收一个keyword,并返回标题中包含keyword的书的数量.
models.py
from django.db import models # 自定义模型管理器类
class BookManager(models.Manager):
#自定义模型管理器中的方法
def title_count(self, keyword):
return self.filter(title_icountains=keyword).count() class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
...
objects = BookManager() def __str__(self):
return self.title
1.我们创建一个BookManager类,继承自django.db.models.Manager.它只有一个方法title_count(),来进行统计.注意,这个方法使用了self.filter(),这个self指manager本身.
2.将BookManager()赋值给模型的objects属性.它将取代模型的默认manager(objects).把它命名为objects是为了与默认的manager保持一致.
现在我们可以进行下面的操作:

这样我们可以将经常使用的查询进行封装,就不必重复写代码了.
修改初始Manager Queryset
manager的基础Queryset返回系统中的所有对象.例如,Book.objects.all()返回book数据库中的所有书籍.你而已通过覆盖Manager.get_queryset()方法来重写manager的基础Queryset.get_queryset()应该按照你的需求返回一个Queryset.
例如,下面的模型有两个manger--一个返回所有对象,另一个仅返回作者是Roald Dahl的书
from django.db import models #首先,定义一个Manager的子类
class DahlBookManager(models.Manager):
def get_queryset(self):
return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl') # 然后,将它显式地插入到Book模型中
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
...
objects = models.Manager() # 默认Manager
dahl_objects = DahlBookManager() # 自定义的特殊Manager
在这个示例模型中,Book.objects.all()将返回数据库中的所有书籍,而Book.dahl_objects.all()只返回作者是Roald Dahl的书籍.注意我们明确的将objects设置为默认Manger的一个实例,因为如果我们不这样做,那么dahl_objects将成为唯一一个可用的manager.
由于get_queryset()返回一个Queryset对象,所以你可以使用filter(),exclude()和其他所有的Queryset方法.
如果你使用自定义的Manager对象,请注意,Django遇到的第一个Manager(以它在模型中被定义的位置为准)会有一个特殊状态。 Django将会把第一个Manager 定义为默认Manager ,Django的许多部分(但是不包括admin应用)将会明确地为模型使用这个manager。 结论是,你应该小心地选择你的默认manager。因为覆盖get_queryset()了,你可能接受到一个无用的返回对像,你必须避免这种情况.
举个栗子:
models.py:
class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager,self).get_queryset().filter(isDelete=False)
#在自定义管理器中定义一个方法创建对象
def createStudents(self,name, age, gender, contend, grade, isD = False):
stu = self.model()
#print(type(stu))
stu.sname = name
stu.sage = age
stu.sgender = gender
stu.scontend = contend
stu.sgrade = grade
return stu
class Students(models.Model):
#xx.objects.all()里的objects是一个Manager()对象
#如果有了新的Manager()对象,原来的objects就不能用了,除非新的Manager()对象命名也是objects
stuObj = models.Manager() #stuObj就相当于原来的objects
stuObj2 = StudentsManager() #stuObj2相当于有一个过滤条件(isDelete=False)的objects
sname = models.CharField(max_length=20)
sgender = models.BooleanField(default=True)
sage = models.IntegerField(db_column='age')
scontend = models.CharField(max_length=20)
isDelete = models.BooleanField(default=False)
sgrade = models.ForeignKey("Grades")
def __str__(self):
return self.sname
# lastTime = models.DateTimeField(auto_now=True)
# createTime = models.DateTimeField(auto_now_add=True)
class Meta:
#改变数据库库名
db_table = "students"
#排序
ordering = ['id'] #在模型类中定义一个类方法创建对象 cls相当于Students类
@classmethod
def createStudents(cls, name, age, gender, contend, grade, isD = False):
stu =cls(sname = name, sage = age,sgender = gender,scontend = contend, sgrade = grade, isDelete = isD)
return stu
views.py:
def students(request):
studentsList = Students.stuObj.all()
return render(request, 'myApp/students.html',{'students':studentsList}) def stupage(request,page):
page = int(page)
studentsList = Students.stuObj2.all()[(page-1)*5:page*5]
return render(request, 'myApp/students.html',{'students':studentsList}) #通过类方法创建对象
def addstudent(request):
grade = Grades.objects.get(pk=1)
stu = Students.createStudents("刘德华",34,True,"我叫刘德华",grade)
stu.save()
return HttpResponse('ok') #通过自定义管理器里的方法创建对象
def addstudent2(request):
grade = Grades.objects.get(pk=1)
stu = Students.stuObj2.createStudents("张学友",43,True,"我叫张学友",grade)
stu.save()
return HttpResponse('ok2')
2.自定义模型方法
为了给你的对像添加一个行级功能,那就定义一个自定义方法.鉴于manager经常被用来用一些整表操作(table-wide).模型方法应该只对特殊模型实例起作用.
from django.db import models class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField() def baby_boomer_status(self):
# Returns the person's baby_boomer status
import datetime
if self.birth_date < datetime.date(1945, 8, 1):
return 'Pre-boomer'
elif self.birth_date < datetime.date(1965, 1, 1):
return 'Baby boomer'
else:
return 'Post-boomer' def _get_full_name(self):
# Return the person's full name
return f'{self.first_name} {self.last_name}'
full_name = property(_get_full_name) # 将类方法包装为属性
这些方法的使用:

Django 自定义模型管理器(Manager)及方法的更多相关文章
- Django中自定义模型管理器(Manager)及方法
1.自定义管理器(Manager) 在语句Book.objects.all()中,objects是一个特殊的属性,通过它来查询数据库,它就是模型的一个Manager.每个Django模型至少有一个ma ...
- Django 自定义模型管理器类2个应用场景
class BookManager(models.Manager): # 改变查询集的结果集 def all(self): books = super().all() # QuerySet books ...
- Django之模型管理器filter处理问题
今天上班第一天,恭祝所有朋友新年快乐!! 最近在github上发现一个还不错的基于Django的开源博客项目,不过也许是版本原因,其中代码存在着些许问题,今天主要记录下其中的模型处理方法的部分. 这段 ...
- 查询集 QuerySet和管理器Manager
查询集 QuerySet 查询集,也称查询结果集.QuerySet,表示从数据库中获取的对象集合. 当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表): all():返回所有数据. ...
- Django ORM 查询管理器
Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...
- (转)Java 的swing.GroupLayout布局管理器的使用方法和实例
摘自http://www.cnblogs.com/lionden/archive/2012/12/11/grouplayout.html (转)Java 的swing.GroupLayout布局管理器 ...
- win2008以上的系统,在vmware esxi5.5里怎么使用自定义规范管理器?sysprep
经过测试,原来08以上的系统自带了sysprep.exe,所以vcenter对08以上的系统直接使用自定义规范管理器即可,跟linux一样了.注意不要跟03一样写入了sn即可. vCenter可使用s ...
- Django 源码小剖: Django ORM 查询管理器
ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...
- 自定义缓存管理器 或者 Spring -- cache
Spring Cache 缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存. 本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 c ...
随机推荐
- git使用记录二: 给文件重命名的简单方法
git使用记录三: 给文件重命名的简单方法 git mv file_name_old file_name_new mv: 文件命名 file_name_old : 文件当前的名字 file_name_ ...
- 如何让Jmeter压力测试减少压力机的资源消耗
如下是官方的一些建议: 1. 使用非gui模式,例如 jmeter -n -t test.jmx -l test.jtl 2. 尽量用较少的监听器(listeners):如果使用了-l 标致像上面一样 ...
- css中的文本字间距离、行距、overflow
css字间距.div css字符间距样式实例1.text-indent设置抬头距离css缩进 div设置css样式text-indent : 20px; 缩进了20px 2.letter-spacin ...
- DB2实例
实例是逻辑数据库管理环境,可以在此环境中对数据库进行编目和设置配置参数.根据需要, 可以在一台服务器上创建多个实例,该服务器为每个实例提供唯一的数据库服务器环境. 默认实例:DB2 显示实例: ...
- how to use gflags
参考https://blog.csdn.net/jcjc918/article/details/50876613 安装: git clone https://github.com/gflags/gfl ...
- linux 系统磁盘管理体系
目录 linux 系统磁盘管理体系 一.磁盘的基本概念 二.磁盘的内部结构 三.磁盘的外部结构 四.磁盘的接口及类型 五.fdisk磁盘分区实践 六.gdisk 分区 七.parted 高级分区工具. ...
- The Preliminary Contest for ICPC Asia Nanjing 2019 D. Robots
题意:给出一个DAG,一只机器人从1点出发,等概率地选择一条出边走或者停留在原点,机器人的第k次行动消耗能量是k(无论是走还是停留都算一次行动).问1到n的期望. 解法:因为行动消耗的能量跟行动次数有 ...
- 有趣的taskset命令,使进程再指定CPU上运行
前言 taskset命令,用于进程的CPU调优,可以把某进程,指定再某CPU内工作. 如还不明白,可以参考此文 http://www.361way.com/linux-context-switch/5 ...
- 由hbase.client.scanner.caching参数引发的血案(转)
转自:http://blog.csdn.net/rzhzhz/article/details/7536285 环境描述 Hadoop 0.20.203.0Hbase 0.90.3Hive 0.80.1 ...
- jQuery 实现表格变色效果
html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...