转载自: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)及方法的更多相关文章

  1. Django中自定义模型管理器(Manager)及方法

    1.自定义管理器(Manager) 在语句Book.objects.all()中,objects是一个特殊的属性,通过它来查询数据库,它就是模型的一个Manager.每个Django模型至少有一个ma ...

  2. Django 自定义模型管理器类2个应用场景

    class BookManager(models.Manager): # 改变查询集的结果集 def all(self): books = super().all() # QuerySet books ...

  3. Django之模型管理器filter处理问题

    今天上班第一天,恭祝所有朋友新年快乐!! 最近在github上发现一个还不错的基于Django的开源博客项目,不过也许是版本原因,其中代码存在着些许问题,今天主要记录下其中的模型处理方法的部分. 这段 ...

  4. 查询集 QuerySet和管理器Manager

    查询集 QuerySet 查询集,也称查询结果集.QuerySet,表示从数据库中获取的对象集合. 当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表): all():返回所有数据. ...

  5. Django ORM 查询管理器

    Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...

  6. (转)Java 的swing.GroupLayout布局管理器的使用方法和实例

    摘自http://www.cnblogs.com/lionden/archive/2012/12/11/grouplayout.html (转)Java 的swing.GroupLayout布局管理器 ...

  7. win2008以上的系统,在vmware esxi5.5里怎么使用自定义规范管理器?sysprep

    经过测试,原来08以上的系统自带了sysprep.exe,所以vcenter对08以上的系统直接使用自定义规范管理器即可,跟linux一样了.注意不要跟03一样写入了sn即可. vCenter可使用s ...

  8. Django 源码小剖: Django ORM 查询管理器

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...

  9. 自定义缓存管理器 或者 Spring -- cache

    Spring Cache 缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存. 本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 c ...

随机推荐

  1. Visual C++中error spawning cl.exe解决办法

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 今天安装Vc6.0的时候出现了一个error spawning cl.exe的错误,在网上找了一些资料,才知道这是因为路径设置的问题引起的 ...

  2. 讲真,下次打死我也不敢随便改serialVersionUID了

    讲真,下次打死我也不敢随便改serialVersionUID了 码农沉思录 码农沉思录 微信号 code-thinker 功能介绍 笔者为国内某知名企业不知名码农,专注Java Web领域多年,有丰富 ...

  3. HttpClient 之 4.x.x版本以上的发送Https请求

    https请求比http更安全 是在http的基础上加了SSL数据加密协议. http的连接很简单,是无状态的:HTTPS协议是由SSL+HTTP协议构建的可进行加密传输.身份认证的网络协议,比htt ...

  4. Python之随机选择 random

    随机选择:random import random # 从一个序列中随机的抽取一个元素 values=[1,2,3,4,56] # 指定取出N个不同元素 print(random.sample(val ...

  5. Python3学习笔记——类

    #!/usr/bin/env python #-*- coding:utf-8 -*- #面向对象(类+对象) 三大特性:封装.继承.多态 类的成员: 字段: 普通字段:保存在对象(实例)中,执行只能 ...

  6. 详细介绍如何计算两条折线的交点并使用Echarts展示以及图表优化

    1.背景 前段时间公司有个需求,需要在一个图表中展示两条折线,并且绘制出两条线的交点.为了满足需求大哥的需求,我也是着实想了有一会.下面我就把具体的实现过程给大家展示一下. 1.1.ECharts 简 ...

  7. C常量与变量

    /** * C中的常量与变量 * 常量的值在程序中是不可变化的,其在定义时必须给一个初始值 * 常量的定义方式: * 1.#define 定义宏常量 * 2.const 定义const常量 * 对于# ...

  8. javascript基础六(事件对象)

    1.事件驱动     js控制页面的行为是由事件驱动的.          什么是事件?(怎么发生的)     事件就是js侦测到用户的操作或是页面上的一些行为       事件源(发生在谁身上)   ...

  9. LeetCode Array Easy 268. Missing Number

    Description Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one th ...

  10. SET SESSION AUTHORIZATION - 为当前会话设置会话用户标识符和当前用户标识符

    SYNOPSIS SET [ SESSION | LOCAL ] SESSION AUTHORIZATION username SET [ SESSION | LOCAL ] SESSION AUTH ...