Django自定義管理器
阿新 • • 發佈:2018-12-30
在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