表数据的操作(增删改查)
表关系的增删改查
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()