2018-11-29 模型关系之一对多

一、一对多关系中的反正向查询

  1.1 定义学生和班级模型

class Grade(models.Model):
    gname = models.CharField(max_length=20)
    create_time = models.DateField(auto_now_add=True)

    class Meta:
        db_table = 'tb_grade'

class Student(models.Model):
    name = models.CharField(max_length=10, unique=True)

    # 定义外键(一对多关系中外键在多的一边)
    grade = models.ForeignKey(Grade, null=True)
    class Meta:
        # 指定Student模型映射到数据库中时,对应的表名。
        db_table = 'tb_student'

  1.2 对学生和班级进行反正向查询

# 正向查询
def sel_grade_by_stu(request):
    """通过学生查对应的班级"""
    stu = Student.objects.filter(name='大明').first()
    stu_grade = stu.grade
    gname = stu_grade.gname
    return HttpResponse(f'{stu.name}\t{gname}')

# 反向查询
def sel_stu_by_grade(request):
    """通过班级查询班级所有学生"""
    grade = Grade.objects.filter(id=15).first()
    stus = grade.student_set.all()
    names = [stu.name for stu in stus]

    return HttpResponse(f'{names}')

一对多关联查询时,当多的查一的需要用 对象.模型名小写 如:stu.grade
当一的查多的需要用 对象.模型名_set(返回的是关联关系) 如: grade.student_set.all() 查看所有的查询集

二、多对多关联查询

  2.1 在上面的基础上再创建一个课程模型(学生和课程就是多对多关系)

class Course(models.Model):
    cname = models.CharField(max_length=10)
    # 定义多对多关联
    stu = models.ManyToManyField(Student)

    class Meta:
        db_table = 'tb_course'

注意:ManyToManyField 字段定义在需要关联的任何一个模型中都可以,迁移时会产生一张第三张表,用于维持多对多关系
此时多对多关系就可以看成第三表和另外两张表的两个一对多关系

  2.2 多对多关联查询

    通过学生查询学生课程,并添加课程
    stu = Student.objects.filter(name='大明').first()
    cou = Course.objects.filter(cname='高数').first()
    # 添加课程 add(对象)
    # stu.course_set.add(cou)
    
    # 移除课程 remove(对象)
    stu.course_set.remove(cou)

多对多关联查询与一对多关系中的反正向查询类似,主要注意set的使用情况

你可能感兴趣的:(2018-11-29 模型关系之一对多)