暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

20200214-16Django模型一对多的关系

智趣智学 2020-02-26
183

模型一对多的关系

外键在哪个表中哪个表就是从表需要注意的是即使代码外键写有级联删除代码但也要手动使用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

模型类如下 


文章转载自智趣智学,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论