模型对应关系
OneToOneField 一对一关系
1.创建模型
创建学生模型
class Student(models.Model):
stu_name = models.CharField(max_length=10)
stu_sex = models.BooleanField()
stu_birth = models.DateField()
stu_create_time = models.DateTimeField(auto_now_add=True)
stu_operate_time = models.DateTimeField(auto_now=True)
stu_yuwen = models.DecimalField(max_digits=3, decimal_places=1)
stu_math = models.DecimalField(max_digits=3, decimal_places=1)
class Meta:
db_table = 'stu'
创建学生额外信息模型
class StudentInfo(models.Model):
stu_addr = models.CharField(max_length=30)
stu_age = models.IntegerField()
stu = models.OneToOneField(Student,
on_delete=models.CASCADE,
related_name='stu_info')
class Meta:
db_table = 'stu_info'
注意:使用model.OneToOneField()进行关联。上表中在数据库中的关联字段为 stu_id
2.通过学生表获取扩展表信息
stu = Student.objects.all().first()
stuInfo = stu.studentinfo
注意: 找到学生表信息再点扩展表信息,扩展表要小写
另外还可在OneToOneField中加入参数related_name=’xxx’
stu = Student.objects.all().first()
stuInfo = stu.xxx
3.通过扩展表获取学生表信息
stuinfo = StuInfo.objects.all().first()
student = stuinfo.stu
注意:找到学生扩展表信息再去直接点关联字段即可
4.设置对应关系的字段为保护模式
- models.CASCADE 默认值
- models.PROTECT 保护模式
- models.SET_NULL 置空模式
- models.SET_DETAULT 置默认值
- models.SET() 删除的时候吃重新动态指向一个实体访问对象元素
例如:
models.OneToOneField('Student', on_delete=models.SET_NULL, null=True)
在删除Student对象后,其关联字段将会将置为空,如下方法删除
Student.objects.filter(id=1).delete()
5.定义on_delete=models.PROTECT
p = Student.objects.all().first()
p.delete()
注意:这个时候再删除就会报错
ForeignKey 一对多关系
1.创建一个班级表一个学生表
# 班级模型
Class Grade(models.Model):
g_name = models.CharField(max_length=16)
# 学生模型
class Student:
s_name = models.CharField(max_length=10)
s_age = models.IntegerField(default=1)
s_grade = models.ForeignKey(Grade, on_delete=PROTECT)
注意:使用models.ForeignKey关联 获取对象元素 grade.student_set
2.获取数据
语法:通过一获取多的数据
公式: 一的对象.多的模型_set
然后在获取数据all(), get(), filter() 等等
如下先通过学生去获取班级信息:
stu = Student.objects.first()
stu.stu_grade
如下是通过班级获取学生信息:
g = Grade.objects.all().first()
g.stugrade.all() ---> 其中stugrade是定义的related_name参数
注意:定义了related_name字段以后,只能通过related_name去反向获取数据,在也不能通过_set方法去获取数据了
3.性能对比
#获取班级的学生(通过一获取多)
#1. 低性能方法:
g = Grade.objects.all().first()
s = Student.objects.filter(s_grade=g)
#2. 高性能方法:
g = Grate.objects.all().first()
s = g.student_set.all()
4.相关练习
# 1. 获取python班下的所有学生的信息
gs = Grade.objects.filter(g_name='python')[0]
allstu = gs.student_set.all()
# 2. 获取python班下语文成绩大于80分的女学生
gs = Grade.objects.filter(g_name='python')[0]
allstu = gs.student_set.filter(stu_yuwen__gte=80)
# 3. 获取python班下语文成绩超过数学成绩10分的男学生
gs = Grade.objects.filter(g_name='python')[0]
allstu = gs.student_set.filter(stu_yuwen__gte=F('stu_shuxue') + 10)
# 4. 获取出生在80后的男学生,查看他们的班级
gs = Grade.objects.filter(g_name='python')[0]
allstu = gs.student_set.filter(stu_birth__gte='1980-01-01', stu_birth__lte='1990-01-01')
ManyToManyField 多对多关系
1.创建一个用户表,一个商品表
#定义购物车,用户的例子实现多对多:
#1. 创建用户模型:
class GoodsUser(models.Model):
u_name = models.CharField(max_length=32)
#2. 创建商品模型:
class Goods(models.Model):
g_name = models.CharField(max_length=32)
g_user = models.ManyToManyField(User)
2. 多对多表结构
多对多关系:
- 生成表的时候会多生成一张表(实际会有三张表)
- 生成的表是专门用来维护关系的
- 生成的表是使用两个外键来维护多对多的关系
- 两个一对多的关系来实现多对多的实现
- 删除一个表的数据的话,中间关联表也要删除相关的信息
3. 练习题
#1 获取第一个用户购买了那些商品
gu = GoodsUser.objects.all().first()
allstu = gu.goods_set.all()
#2 获取指定商品的购买用户信息
g = Goods.objects.filter(id=1)[0]
g.g_user.all()