Django自定義管理器
在Django中,我們有些時候使用Django自帶的ORM語句無法達到操作資料庫的效果,這時,我們可以自定義一個管理器來進行資料庫的操作。從總體上來說,就是重寫方法和自定義方法
因為不同的操作在不同的類中,如all() 在Manager類,get()在Query類中,所以通過例子說明。
model類:
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30,null=False)
sgender = models.BooleanField(default=False)
def __str__(self):
return "Student:%s--%s"%(self.sname,self.sgender)
資料庫表數據:
例1:如何通過Student.objects.all() 查詢sgender為True的記錄?
思路:創建一個類,繼承Manager,然後在這個類中重寫all()方法。在all()方法中添加功能。然後在model類中,定義一個objects屬性,使它成為類對象。(方法有很多,這是其中之一)
代碼如下:
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30,null=False)
sgender = models.BooleanField(default=False)
objects = getAllTrue() #創建一個自定義類對象
def __str__(self):
return "Student:%s--%s"%(self.sname,self.sgender)
#自定義管理類
class getAllTrue(Manager): #all()來自於Manager類
# def all(self): #重寫方法
# return Manager.all(self).filter(sgender = True) #功能操作
#-----def get_queryset(self): 與all() 方法相同,
#在源碼中,all()執行就是調用get_queryset()方法。
def get_queryset(self):
return Manager.get_queryset(self).filter(sgender=True)
#查詢結果:
Student.objects.all()
#Out[3]: <QuerySet [<Student: Student:zhangsan--True>, <Student: Student:zhaoliu--True>, <Student: Student:qianqi--True>]>
例2:如何使用Student.objects.filter().delete()方法,批量修改sgender=Flase的記錄為True。
思路:創建一個類,繼承Manager,然後在這個類中重寫filter()方法。在filter()方法中添加功能。然後在model類中,定義一個objects屬性,使它成為類對象。(方法有很多,這是其中之一)
代碼如下:
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30,null=False)
sgender = models.BooleanField(default=False)
objects = batchDelManager() #創建一個自定義類對象
def __str__(self):
return "Student:%s--%s"%(self.sname,self.sgender)
#自定義管理類
class batchDelManager(Manager):
def filter(self, *args, **kwargs):
delList = Manager.get_queryset(self) #獲取所有sgender=False記錄
#閉包,執行修改操作
def del1(queset):
for que in queset:
que.sgender = True
que.save()
import types
#動態生成方法,使filter().delete()執行del1()方法。
#types.MethodType在2.x中不能使用,###python2.x使用 new.instancemethod 該方法在python3.x中刪除
delList.delete = types.MethodType(del1,delList)
return delList
def get_queryset(self):
return Manager.get_queryset(self).filter(sgender=False)
執行代碼:
Student.objects.filter().delete()
資料庫結果:
例3:Student.objects.create(sname="xiaoming",cls="PythonDjango班",cour=("Python","Django","JS"))不管主外鍵,直接插入,重寫create方法。
代碼如下:
from django.db import models
from django.db.models.manager import Manager
#自定義管理類
class CustomManager(Manager):
#插入班級,以班級作為對象返回
def getClazz(self,cname):
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
return cls
#插入課程,以對象列表返回
def getcourList(self,course):
courList = []
for co in course:
try:
cour = Course.objects.get(course_name=co)
except Course.DoesNotExist:
cour = Course.objects.create(course_name=co)
courList.append(cour)
return courList
def create(self, **kwargs):
cname = kwargs["cls"]
clazz = self.getClazz(cname)
kwargs["cls"] = clazz #班級
course = kwargs.pop("cour") #拋出課程給course
stu = Manager.create(self,**kwargs) #保存學生
courseList = self.getcourList(course)
stu.cour.add(*courseList) #添加學生與課程的連接
# Create your models here.
class Clazz(models.Model):
cno = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
def __str__(self):
return "Clazz:%s"%self.cname
class Course(models.Model):
course_no = models.AutoField(primary_key=True)
course_name = models.CharField(max_length=30)
def __str__(self):
return "Course:%s"%self.course_name
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30)
cls = models.ForeignKey(Clazz,on_delete=models.CASCADE)
cour = models.ManyToManyField(Course)
objects = CustomManager()
def __str__(self):
return "Student:%s"%self.sname
※MySQL資料庫開發的36條鐵律
※springboot websocket後台主動推送消息
TAG:程序員小新人學習 |