模型一对多的关系:
外键在哪个表中,哪个表就是从表,需要注意的是即使代码外键写有级联删除代码,但也要手动使用Nvicat修改一下外键,因为这里的级联删除不起作用,不知道是不是一个bug。
举例子:
下面有2张表,一张班级表,一张学生表:
#班级表
class Clazz(models.Model):
con = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
#学生表
class Student(models.Model):
sno = models.AutoFiels(primary_key=True)
sname=models.CharField(max_length=30)
如何把学生表变为一对多关系的从表呢?
分析:一个班级肯定有好多学生,所以我们把班级定做主表,把学生定做从表,他们之间的关系是一对多的关系,将学生表变为从表,我们只需要在学生表里加上下面一句话:
con = models.ForeignKey(Clazz,on_delete=models.CASCADE)
这句话的意思是:学生表里出来有学生自己的snoID号之外,还有一个外键关联班级的conID号。复制后的变量名称con最好和主表中的id名称con一致。
#班级主表
class Clazz(models.Model):
con = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
#学生从表
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30)
con = models.ForeignKey(Clazz,on_delete=models.CASCADE)
def __str__(self):
return smart_str('Student:%s'%self.sname)
实战:
(1)主表中插入2个班级
from stu.models import *
cls = Clazz.objects.create(cname='B201Python')
cls1=Clazz.objects.create(cname='B202Java')
(2)从表中插入学生张三和李四,班级是B201python,插入王五班级是B202Java
Student.objects.create(sname='zhangsan',con=cls)
Student.objects.create(sname='lisi',con=cls)
Student.objects.creat(sname='wangwu',con=cls1)
(3)通过主表中第一条记录查询从表里面的所有信息
Clazz.objects.first().student_set.all()
解释:因为从表中存在多条记录,而set是集合的意思。
(4)通过从表中的一条记录查询其所对应的主表信息
Student.objects.first().con
解释:因为从表中的外键con所对应的对象就是主表Clazz《co=models.ForeignKey(Clazz,on_delete=models.CASCADE)》
技巧1:
我们在给从表设置外键的时候,还可以使用related_name=''给从表类名进行重命名,
作用就是当我们使用正向查询的时候:
未命名前:
外键:con=models.ForeignKey(Clazz,on_delete=models.CASCADE)
查询:Clazz.objects.first().student_set.all()
命名后:
外键con=models.ForeignKey(Clazz,on_delete=models.CSSCADE,related_name='sts')
查询:Clazz.objects.first().sts.all()
技巧2:
封装一个多表插入的方法,当我们需要如数据的时候直接调用该方法即可
def inserData(clsname,*snames):
try:
cls=Clazz.objects.get(cname=clsname)
except Clazz.DoesNotExit:
cls = Clazz.objects.create(cname=clsname)
for sn in snames:
try:
stu=Student.objects.get(sname=sn)
except Student.DoesNotExit:
Student.objects.create(sname=sn,con=cls)
inserData('B203HTML5班','张三丰','谢逊')
封装函数解释:
先查询我们输入的班级名称是否存在,如果存在就不执行,如果不存在就创建,然后遍历我们输入的姓名,如果存在就不执行,如果不存在就创建
封装函数里面的cname是数据库班级表里面的班级名称字段,sname数据库学生表里的学生名称字段
*args:将收集所有位置相关参数,并放置到一个元组中,最后将这个元组赋值给args
**kwargs:针对关键字参数(指a=3这一类型)这些关键字参数会放到一个相应的字典中,然后同样的赋值给kwargs
模型类如下:





