Django中的关系映射
导言
学习Django的ORM需要掌握三个维度
- 如何建表
- 如何建立数据
- 如何对数据进行查询
一对一
一个人对应一个身份证
语法 OneToOneField
class People(models.Model):
...
class Sfz(models.Model):
ren = models.OneToOneField(People,on_delete=models.CASCADE) #级联删除
- on_delete
- models.CASCADE 【级联删除,包括ForeignKey的对象】
- models.PROTECT 【阻止删除】
- SET_NULL 【设置ForeignKey null,需提前指定null=True,即可以删除,删除后外键为空】
创建
- 无外键->人
people1 =People.objects.create(...)
- 有外键->身份证
sfz1 = Sfz.objects.create(...,[people_id=1]|[people=people1])
查询
- 正向查询:直接通过外键属性查询
from .models import people
sfz1 = Sfz.objects.get(id='sfz1')
# 查找people1的身份证id
sfz1.people.name
- 反向查询:没有外键属性的一方,可以通过反向属性查询到关联的另一方
!!反向引用不存在时会触发异常
people1 = people.objects.get(name='people1')
# 查找人1的身份证id
people1.Sfz.id
一对多
一个班级对应多个学生
原则上是在多这一端的表上设置外键
语法 ForeignKey
class Student(models.Model):
classroom = models.ForeignKey(Classroom,on_delete=models.CASCADE) #级联删除
class Classroom(models.Model):
...
创建
- 先创建一,后创建多
classroom = Classroom.objects.create(name="1班")
student1 = Student.objects.create(name="zhangsan",classroom=classroom)
or
student1 = Student.objects.create(name="zhangsan",classroom_id=1)
查询
- 正向查询
classroom = Classroom.objects.get(name="1班")
student1 = Student.objects.get(name="zhangsan",classroom=classroom)
or
student1 = Student.objects.get(name="zhangsan",classroom_id=1)
- 反向查询
classroom1 = Classroom.objects.get(name="1班")
students = classroom1.student_set.all()
for student in students:
print(student.name)
多对多
一个学生对应多门课程,一个课程对应多名学生
语法ManyToManyField
- 无需创建第三张表,Django自动完成
class Student(models.Model):
name = models.CharField('name')
class Course(models.Model):
coursename = models.CharField('coursename')
student = models.ManyToManyField(Student)
创建
- 先创建student再关联Course
student1和student2同时参加了course1
student1 = Student.objects.create(name="zhangsan")
student2 = Student.objects.create(name="lisi")
course1 = student1.course_set.create(name="chinese")
student2.course_set.add(course1)
- 先创建course再关联student
student1和student2同时参加了course1
student2 = Student.objects.create(name="lisi")
course1 = student1.objects.create(name="chinese")
student1 = course1.student.create(name="zhangsan")
course.student.add(student2)
查询
- 正向查询
student1.course.all() #获取到学生1选择的所有课程
course1.student.all() #获取到course1这门课程下的所有学生
student1.course.filter(name='chinese')
- 反向查询
student1.course_set.all()
course1.student_set.filter()