6、Django模型之表关联对象操作及多表查询

表数据的操作(增删改查)

表关系的增删改查

n—m foreignkey设置在表m中

1、OneToMany(正向,反向操作)

正向::一个模型有外键字段,通过这个模型对外键进行操作就叫正向
class Student(models.Model):
	...
	grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)

反向:一个模型如果被另一个模型外键关联,通过这个模型对关联他的模型进行操作 管理器是student_set

正向

1、增
# 通过属性赋值
In [12]: s1 = Student(name="斜光", age=19, sex=0, qq="123", phone="456", grade=gl)                                                                        

In [13]: s1.save()  

# 主键的方式
In [14]: s2 = Student(name="LC", age=20, qq="1033", phone="173")                                                                                          

In [15]: s2.grade_id = g2.id                                                                                                                              

In [16]: s2.save()     
2、查
In [18]: s1                                                                                                                                               
Out[18]: <Student: 斜光-19>

In [19]: s1.grade                                                                                                                                         
Out[19]: <Grade: Grade object (1)>

In [20]: s2.grade                                                                                                                                         
Out[20]: <Grade: Grade object (2)>

In [21]: s2.grade.name                                                                                                                                    
Out[21]: '爬虫班'

In [24]: Student.objects.filter(grade__name="Django框架")                                                                                                 
Out[24]: <QuerySet [<Student: 斜光-19>]>

3、删(删除关系)
In [26]: s2.grade = None                                                                                                                                  

In [27]: s2.save()  

反向操作

如果说一个模型(eg:student)有一个ForeignKey(grade)那么这个外键模型的实例(eg:g1)将可以返回一个Student模型的所有实例的管理器(student_set)(student是模型名,小写)

1、增add
# 通过student_set管理器
In [29]: new_s = g2.student_set.create(name="CL", age=19, qq="223", phone="189")      

# 一次增加多个数据
In [3]: s1, s2, s3 = Student.objects.filter(id__lte=3)  

In [7]: g1.student_set.add(s1,s2,s3)    
2、改set
In [15]: g2.student_set.set([s2,s3]) 
3、删
# remove
In [16]: g2.student_set.remove(s2,s3) 

# clear
In [18]: g2.student_set.clear() 
4、查
In [19]: g1.student_set.all()                                                                                                                             
Out[19]: <QuerySet [<Student: 斜光-19>]>

In [21]: g1.student_set.filter(age=19)                                                                                                                    
Out[21]: <QuerySet [<Student: 斜光-19>]>


2、ManyToMany

class Course(models.Model):
    ...
    students = models.ManyToManyField('Student', through='Enroll')   # through='Enroll':通过Enroll表与Student表关联
正向:通过Course操作Student,objects
反向:管理器是course_set

指定反向模型管理器名字
在这里插入图片描述
可以通过relatede_name来指定属性来替代course_set

1、增
In [2]: from students.models import Student, StudentDetail, Course, Grade, Enroll                                                                         

In [3]: c1 = Course.objects.create(name="python")                                                                                                         

In [4]: s1 = Student.objects.first()  

In [8]: e = Enroll()                                                                                                                                      

In [9]: e.course = c1                                                                                                                                     

In [17]: e.student = s1                                                                                                                                   

In [18]: e.save()    
正向
In [21]: c1.students.all()                                                                                                                                
Out[21]: <QuerySet [<Student: 斜光-19>]>

In [22]: s1.course.all()                                                                                                                                  
Out[22]: <QuerySet [<Course: Course object (1)>]>

3、OneToOne

正向:一对一字段所在模型,通过这个模型去访问关联的模型

In [23]: d1 = StudentDetail(college="武汉理工大学")                                                                                                       

In [24]: d1.student = s1                                                                                                                                  

In [25]: d1.save() 
In [2]: StudentDetail.objects.values('college', 'student__name', 'student__qq')                                                                           
Out[2]: <QuerySet [{'college': '武汉理工大学', 'student__name': '斜光', 'student__qq': '123'}]>

反向:前面的反向是通过管理器,而一对一中反向类似正向
通过原始模型的小写模型名加双下划线跨表查询

In [3]: s = Student(name='鲁路修', age='18', qq='2256', phone='176')                                                                                      

In [4]: s.studentdetail = d1  

In [8]: Student.objects.values('name', 'qq', 'studentdetail__college')   
                                                                                 
Out[8]: <QuerySet [{'name': '斜光', 'qq': '123', 'studentdetail__college': '武汉理工大学'}, 
{'name': 'LC', 'qq': '1033', 'studentdetail__college': None},
'CL', 'qq': '223', 'studentdetail__college': None},
{'name': '鲁路修', 'qq': '2256', 'studentdetail__college': None}]>

跨表查询: 小写模型名__(双下划线)

如果想跨表,只需要使用跨模型的相关字段字段名,以双下划线隔开,直到到达想要的结果为止

# 男生报名的课程
In [116]: Course.objects.filter(students__sex=1)                                                                                                          
Out[116]: <QuerySet [<Course: Course object (1)>, <Course: Course object (1)>]>

# 报名了python课程的学员
In [117]: Student.objects.filter(course__name='python')                                                                                                   
Out[117]: <QuerySet [<Student: 斜光-19>, <Student: LC-20>, <Student: CL-19>]>

# 报名了python课程的学员且班期为11期的
In [118]: Student.objects.filter(course__name='python', grade__num__contains='11期')                                                                      
Out[118]: <QuerySet [<Student: LC-20>]>

# 查询缴费金额小于300的学员
In [120]: e = Enroll()                                                                                                                                    

In [121]: c2 = Course.objects.create(name='English')                                                                                                      

In [122]: e.course = c2                                                                                                                                   

In [123]: e.student = s4                                                                                                                                  

In [124]: pay = 1000                                                                                                                                      

In [125]: e.save()                                                                                                                                        

In [126]: Student.objects.filter(enroll__pay__lt=3000)                                                                                                    
Out[126]: <QuerySet [<Student: 斜光-19>, <Student: LC-20>, <Student: CL-19>, <Student: 鲁路修-18>]>

# 报了某课程名的学生班级有哪些
In [128]: Grade.objects.filter(student__course__name__icontains='english')                                                                                
Out[128]: <QuerySet [<Grade: Grade object (3)>]>

# 去重.distinct()
In [3]: Grade.objects.filter(student__course__name="English").distinct() 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值