注意:
本实验是接着 《Django 数据展示(多对多版)》而继续的
正文:
步骤一:在没有自定义 manager 管理器的情况下尝试一次性完成多对多表数据的插入
1.1 进入相应的 Django 环境
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *
1.2 在没有自定义 manager 管理器的情况下尝试一次性完成多对多表数据的插入
>>> Student.objects.create(sname='lili',clazz='Class1',course=('Python','Shell'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/zhumingyu/Code/Django/mtwo/django_env/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/zhumingyu/Code/Django/mtwo/django_env/lib/python3.8/site-packages/django/db/models/query.py", line 451, in create
obj = self.model(**kwargs)
File "/Users/zhumingyu/Code/Django/mtwo/django_env/lib/python3.8/site-packages/django/db/models/base.py", line 503, in __init__
raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))
TypeError: Student() got an unexpected keyword argument 'clazz'
(
补充:
(1)这里数据插入失败
(2)按正常顺序应该是先插入班级 clazz,之后再插入学生 student,之后再插入课程 course,之后再去插入中间表
)
1.3 退出相应的 Django 环境
>>> quit();
步骤二:确认要插入的数据和预期的一致(可选)
2.1 创建 1 个自定义 manager 管理器的类
将 mysite/test/models.py 中的以下内容:
......
class Clazz(models.Model):
cno = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
def __str__(self):
return u'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 u'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)
def __str__(self):
return u'Student:%s'%self.sname
# Get class object according to class name
def getCls(cname):
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
return cls
def getCourseList(*coursenames):
courseList = []
for cn in coursenames:
try:
c = Course.objects.get(course_name=cn)
except Course.DoesNotExist:
c = Course.objects.create(course_name=cn)
courseList.append(c)
return courseList
def registerStu(sname,cname,*coursenames):
#1. Get class objects
cls = getCls(cname)
#2. Gets the list of course objects
courseList = getCourseList(*coursenames)
#3. Insert student table data
try:
stu = Student.objects.get(sname=sname)
except Student.DoesNotExist:
stu = Student.objects.create(sname=sname,cls=cls)
#4. Insert intermediate table data
stu.cour.add(*courseList)
return True
修改为:
......
from django.db import models
from django.db.models.manager import Manager
# Create your models here.
class Clazz(models.Model):
cno = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
def __str__(self):
return u'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 u'Course:%s'%self.course_name
class CustomManager(Manager):
def create(self, **kwargs):
print(kwargs)
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 u'Student:%s'%self.sname
# Get class object according to class name
def getCls(cname):
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
return cls
def getCourseList(*coursenames):
courseList = []
for cn in coursenames:
try:
c = Course.objects.get(course_name=cn)
except Course.DoesNotExist:
c = Course.objects.create(course_name=cn)
courseList.append(c)
return courseList
def registerStu(sname,cname,*coursenames):
#1. Get class objects
cls = getCls(cname)
#2. Gets the list of course objects
courseList = getCourseList(*coursenames)
#3. Insert student table data
try:
stu = Student.objects.get(sname=sname)
except Student.DoesNotExist:
stu = Student.objects.create(sname=sname,cls=cls)
#4. Insert intermediate table data
stu.cour.add(*courseList)
return True
(补充:这里以添加一个显示自己所有键值对的 CustomManager(Manager) 对象并在 Student 类中使用 objects 调用为例)
2.2 进入相应的 Django 环境
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *
2.3 确认要插入的数据和预期的一致
>>> Student.objects.create(sname='lili',clazz='Class1',course=('Python','Shell'))
{'sname': 'lili', 'clazz': 'Class1', 'course': ('Python', 'Shell')}
2.4 退出相应的 Django 环境
>>> quit();
步骤三:一次性完成多对多表数据的插入
3.1 创建 1 个自定义 manager 管理器的类
将 mysite/test/models.py 中的以下内容:
......
class Clazz(models.Model):
cno = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
def __str__(self):
return u'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 u'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)
def __str__(self):
return u'Student:%s'%self.sname
# Get class object according to class name
def getCls(cname):
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
return cls
def getCourseList(*coursenames):
courseList = []
for cn in coursenames:
try:
c = Course.objects.get(course_name=cn)
except Course.DoesNotExist:
c = Course.objects.create(course_name=cn)
courseList.append(c)
return courseList
def registerStu(sname,cname,*coursenames):
#1. Get class objects
cls = getCls(cname)
#2. Gets the list of course objects
courseList = getCourseList(*coursenames)
#3. Insert student table data
try:
stu = Student.objects.get(sname=sname)
except Student.DoesNotExist:
stu = Student.objects.create(sname=sname,cls=cls)
#4. Insert intermediate table data
stu.cour.add(*courseList)
return True
修改为:
......
class Clazz(models.Model):
cno = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
def __str__(self):
return u'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 u'Course:%s'%self.course_name
class CustomManager(Manager):
#Returns a class object
def getClsObj(self,cname):
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
return cls
def getCourseList(self,*coursenames):
cList = []
for cn in coursenames:
try:
cour = Course.objects.get(course_name=cn)
except Course.DoesNotExist:
cour = Course.objects.create(course_name=cn)
cList.append(cour)
return cList
def create(self, **kwargs):
clazz = kwargs.get('cls','')
#Class information multi storage operation
clas = self.getClsObj(clazz)
#Replace string with object
#Student.objects.create(sname='',cls=clas)
kwargs['cls'] = clas
#Assign a separate value pair of course keys to course
course = kwargs.pop('cour')
#Storage operation of student information
stu = Manager.create(self,**kwargs)
#Total of the course information in storage
courseList = self.getCourseList(*course)
#The middle table of student course is stored in the database. An object or tuple can be unpacked automatically here
stu.cour.add(*courseList)
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 u'Student:%s'%self.sname
# Get class object according to class name
def getCls(cname):
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
return cls
def getCourseList(*coursenames):
courseList = []
for cn in coursenames:
try:
c = Course.objects.get(course_name=cn)
except Course.DoesNotExist:
c = Course.objects.create(course_name=cn)
courseList.append(c)
return courseList
def registerStu(sname,cname,*coursenames):
#1. Get class objects
cls = getCls(cname)
#2. Gets the list of course objects
courseList = getCourseList(*coursenames)
#3. Insert student table data
try:
stu = Student.objects.get(sname=sname)
except Student.DoesNotExist:
stu = Student.objects.create(sname=sname,cls=cls)
#4. Insert intermediate table data
stu.cour.add(*courseList)
return True
(补充:这里以创建一次性完成多对多表数据的插入的 manage 管理器为例)
3.2 进入相应的 Django 环境
(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *
3.3 一次性完成多对多表数据的插入
>>> Student.objects.create(sname='lili',cls='Class4',cour=('CSS','JS'))
(
补充:这里
1) 第 1 步执行:objects = CustomManager()
2) 第 2 步执行:def create(self, **kwargs)
3) 第 3 步执行:clazz = kwargs.get(‘cls’,”),这步的结果是 clazz = ‘Class4’
4) 第 4 步执行:clas = self.getClsObj(clazz),这步的结果是如果 Class4 在数据库中不存在则插入此条数据,并让 clas = cls
5) 第 5 步执行:cours = kwargs.pop(‘cour’),这步的结果是 cours = (‘CSS’,’JS’)
6) 第 6 步执行:stu = Manager.create(self, **kwargs),这步的结果是 stu = Student.objects.create(sname=”,cls=clas)
7) 第 7 步执行:courseList = self.getCourseList(*course),这步的结果是如果 course 元组里的元素不存在则在数据库里创建,并将所有 course 里的元素放在 courseList 空列表中
8) 第 8 步执行:stu.cour.add(*courseList),这步的结果是将 courseList 里的元素插入 Student 类的 cour 字段对应的中间表里
)