django模型系统(三)--表关系的实现与一对多关联表的数据操作

表关系实现

1. 表关系的创建
- OneToOne  创建一个学生详情表StudentDetail,与Student表一对一关系

student = models.OneToOneField('Student', on_delete=models.CASCADE)

- OneToMany

grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)

- ManyToMany

学生表(Student)与课程表(Course)之间是多对多的关系,通过中间表关联。中间表分别去外键关联,并且联合唯一

详细model.py如下:

from django.db import models
# Create your models here.

class Student(models.Model):
    name = models.CharField(max_length=20)
    age = models.SmallIntegerField(default=0)
    sex = models.SmallIntegerField(default=1)
    qq = models.CharField(max_length=20,unique=True,null=True)
    phone = models.CharField(max_length=20,unique=True,null=True)
    #删除年级的时候不必把学生都删除,必须可以设置年级字段为null,on_delete=models.SET_NULL,null=True
    grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True)   #一对多关系,与Grade是多对一的关系
    c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
    e_time = models.DateTimeField(verbose_name='编辑时间',auto_now=True)
    is_deleted = models.BooleanField(default=False)
    def __str__(self):
        return '%s-%s-%s' %(self.id,self.name,self.age)

class StudentDetail(models.Model):
    num = models.CharField(max_length=20,default="")
    college = models.CharField(max_length=20,default="")
    #如果把学生删除了,学生详情里面的也要删除on_delete=models.CASCADE(级联操作,保证一直)
    student = models.OneToOneField('Student',on_delete=models.CASCADE)   #与Student表一对一关系,‘Student’字符串更加通用,无论Student模型是在前面后者后面都能使用
 
class Grade(models.Model):
    name = models.CharField(max_length=20)
    num = models.CharField(max_length=20)

    def __str__(self):
        return '%s - %s' %(self.num,self.name)

class Course(models.Model):
    name = models.CharField('课程名称',max_length=20)
    students = models.ManyToManyField('Student',through='Enroll')#与学生是多对多,如果中间表只有两个表的id,则不需要主动创建中间表Enroll,系统自动创建中间表teacher_course_students
    def __str__(self):                                          #如果第三张表中有额外的字段,需要手动创建中间表Enroll
        return self.name

class Enroll(models.Model):  #中间表为报名表
    student = models.ForeignKey('Student',on_delete=models.CASCADE) #中间表分别去外键关联,并且联合唯一
    course = models.ForeignKey('Course',on_delete=models.CASCADE)
    pay = models.FloatField('缴费金额',default=0)
    c_time = models.DateTimeField('报名时间',auto_now_add=True)

2. 关联表的数据操作

一对多关系操作

- OneToMany
- 正向: 一个模型如果定义了一个外键字段,通过这个模型操作外键
增删改查

导入模型,并查看已经创建的数据表数据

In [2]: from teacher.models import Student,StudentDetail,Course,Enroll,Grade                                                                                                                                          

In [3]: Grade.objects.all()                                                                                                                                                                                           
Out[3]: <QuerySet [<Grade: 33期 - django框架>, <Grade: 34期 - 爬虫>]>

In [4]: Student.objects.all()                                                                                                                                                                                         
Out[4]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>]>

正向增加的两种方法:

#1.第一种 通过直接赋值一个已经保存的对象给她
In [5]: s= Student() In [6]: s.name='梦洁' In [7]: g1 = Grade.objects.first() #g1为Grade的对象 In [8]: s.grade = g1 #Grade表必须先创建,不然保存不能成功 In [9]: s.save() In [10]: Student.objects.all() Out[10]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>, <Student: 3-梦洁-0>]>
#2.第二种。赋值给他一个已经保存的Id给他
In [11]: s2 = Student(name = '魏明凯') In [12]: g2 = Grade.objects.last() In [13]: s2.grade_id =g2.id In [14]: s2.save() #Grade必须首先创建 In [15]: Student.objects.all() Out[15]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>, <Student: 3-梦洁-0>, <Student: 4-魏明凯-0>]>

正向更新修改:

In [34]: Student.objects.all()                                                                                                                                                                                       
Out[34]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>, <Student: 3-梦洁-0>, <Student: 4-魏明凯-0>, <Student: 5-litao-0>]>

In [35]: s2= Student.objects.get(id=2)                                                                                                                                                                                                                                                                                                                                                                                          

In [36]: s2                                                                                                                                                                                                          
Out[36]: <Student: 2-litao-0>

In [37]: s1= Grade.objects.first()                                                                                                                                                                                   

In [38]: s2.grade=s1                                                                                                                                                                                                 

In [39]: s2.save()   

正向删除:
删除外键时候定义必须有一个None

grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True)
In [41]: s= Student.objects.first()                                                             

In [42]: s                                                                                      
Out[42]: <Student: 1-心蓝-0>

In [43]: s.grade= None                                                                          

In [44]: s.save()   

正向查:

通过学生表的查询学生所在班级的名称,班级

In [41]: s= Student.objects.first() 
In [49]: s.grade.name 
Out[49]: 'django框架'

In [50]: s.grade.num 
Out[50]: '33期'

反向:

从Grade的对象反过来查和它 关联的student的模型
一个模型如果被另外一个模型外键关联,通过这个模型去对关联它的模型进行操作就叫反向

反向增加

1.直接创建,增加
In [53]: g3 =Grade.objects.create(name='进阶',num='40期') #反向,g3.反向关联字表的小写_set 操作 In [54]: g3.student_set.create(name='刘洋') Out[54]: <Student: 6-刘洋-0> #2.将已经存在的对象添加到g3,add,create都是立刻执行,不需要save() In [55]: s Out[55]: <Student: 1-心蓝-0> In [56]: g3.student_set.add(s)

 反向查询

In [81]: g3.student_set.all()                                                                                                                                                                                         
Out[81]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>, <Student: 6-刘洋-0>]>

In [82]: s3.grade                                                                                                                                                                                                     
Out[82]: <Grade: 40期 - 进阶>

反向修改更新:

#s3 本来是33期,通过反向查询将其修改为40期
#add方法可以添加多个对象#g3.student_set.add(s3,s2,s1)
In [78]: s3 = Student.objects.get(id=2)                                                                                                                                                                               

In [79]: s3.grade                                                                                                                                                                                                     
Out[79]: <Grade: 33期 - django框架>

In [80]: g3.student_set.add(s3)                                                                                                                                                                    

反向删除:

In [89]: g3.student_set.all()                                                                                                                                                                                         
Out[89]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>, <Student: 6-刘洋-0>]>

In [90]: s.name                                                                                                                                                                                                       
Out[90]: '心蓝'

In [91]: g3.student_set.remove(s)                                                                                                                                                                                     

In [92]: g3.student_set.all()                                                                                                                                                                                         
Out[92]: <QuerySet [<Student: 2-litao-0>, <Student: 6-刘洋-0>]>

反向清除:clear

In [95]: g3.student_set.all()                                                                                                                                                                                         
Out[95]: <QuerySet [<Student: 2-litao-0>, <Student: 6-刘洋-0>]>

In [96]: g3.student_set.clear()                                                                                                                                                                                       

In [97]: g3.student_set.all()                                                                                                                                                                                         
Out[97]: <QuerySet []>

反向修改重置:

In [98]: s                                                                                                                                                                                                            
Out[98]: <Student: 1-心蓝-0>

In [100]: s1= Student.objects.get(id=2)                                                                                                                                                                               

In [101]: g3.student_set.set([s,s1])    #接受一个列表,先调用clear,在添加add。如果没有clear再执行add

查询student 表中所有的django框架的学生

In [109]: res = Student.objects.filter(grade__name='django框架')    #关联字段用'__'
In [110]: print(res.query) SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`grade_id`, `teacher_student`.`c_time`, `teacher_student`.`e_time` FROM `teacher_student` INNER JOIN `teacher_grade` ON (`teacher_student`.`grade_id` = `teacher_grade`.`id`) WHERE `teacher_grade`.`name` = django框架

猜你喜欢

转载自www.cnblogs.com/taoge188/p/10506447.html