一、背景:
创建一组一对多的表。
# 班级表
class Class(models.Model):
class_id = models.IntegerField(primary_key=True, verbose_name='班级id', help_text='班级id')
class_name = models.CharField(max_length=20,verbose_name='班级名称', help_text='班级名称')
# 学生信息表
class Student(models.Model):
id = models.AutoField(primary_key=True, verbose_name='id主键', help_text='id主键')
name = models.CharField(max_length=20,verbose_name='姓名', help_text='姓名')
student_id = models.CharField(max_length=10,verbose_name='学号', help_text='学号',unique=True)
# 创建外键,外键需要创建多的那一个表中(从表)
# models.ForeignKey('应用名.主表的类名') 与哪个表建立外键
# on_delete= 外键的级联删除:如果父表中的记录被删除,则子表中对应的记录如何处理
# on_delete=models.CASCADE(),如果父表中的记录被删除,则子表中对应的记录自动被删除
class_name = models.ForeignKey('orders.Class',on_delete=models.CASCADE,verbose_name='班级', help_text='班级')
主表:班级表
从表:学生信息表
注意:
从表,在创建外键的时候
class_name = models.ForeignKey('orders.Class',on_delete=models.CASCADE,verbose_name='班级', help_text='班级')
模型类中,外键的类属性名称为 class_name。但是生成的表中,外键的字段名称为class_name_id。
ORM框架,在生成从表的外键字段名称时,自动在后面追加了一个_id。
二、关联表的数据创建
如何在从表中,插入数据?对于外键数据的处理,有两种方式。
2.1 外键的类的属性名=主表的数据实例
举例:
在Student表中,插入一条学生姓名为 阿珍,所属班级class_id=3 的学生信息。
1、先获取主表的数据实例
2、再通过外键 类的属性名 = 主表的数据实例 创建
def add_student_1(request):
"""
添加一名学生信息。姓名:阿珍。所属班级class_id:3
:param request:
:return:
"""
# 先获取主表的数据实例(班级id为3)
class_obj = Class.objects.get(class_id="3")
# 从表数据,外键绑定主表实例
Student.objects.create(name="阿珍",student_id="0019",class_name=class_obj)
return HttpResponse("成功")
2.2 从表中的外键字段名=具体的值
举例:
在Student表中,插入一条学生姓名为 大红帽,所属班级class_id=3 的学生信息。
Student.objects.create(name="大红帽",student_id="0021",class_name_id=4)
三、关联表的查询
3.1 在从表中,查询主表的相关信息(非关联查询)
通过外键获取
查询 学生姓名 【张红】 所在的【班级】 信息
1、先获取从表的数据实例
2、再通过 从表的数据实例.外键的类属性名称 获取 主表的数据实例
class_ojb=Student.objects.filter(name="张红").first().class_name
print(class_ojb.class_id)
print(class_ojb.class_name)
3.2 在主表中获取从表数据(非关联查询)
通过从表模型类名小写_set_all() 获取
查询班级名称为【二班】的所有学生数据
1、先获取主表的数据实例
2、再通过 从表模型类名小写_set.all()进行关联
或者 表模型类名小写_set.filter(过滤条件)
students_info=Class.objects.filter(class_name="二班")[0].student_set.all()
获取到的值 students_info 是 QuerySet
<QuerySet [<Student: Student object (4)>, <Student: Student object (5)>]>
注意:
从表模型类名小写_set 返回的对象为 manager对象。
3.2.1 related_name
主表的实例 通过从表模型类名小写_set_all() 获取 从表的数据,
这里 【从表模型类名小写_set】 ,我们在创建从表模型类的外键时可以自定义名称,通过
related_name= 实现
创建外键:
class_name = models.ForeignKey('orders.Class',on_delete=models.CASCADE,verbose_name='班级', help_text='班级',related_name="inter")
查询语句:
students_info=Class.objects.filter(class_name="二班")[0].inter_set.all()
3.3 关联查询(这个方式应该是最简单的)
关联查询,不区分主表、从表。查询方式是一样的。
查询班级名称为 三班 的所有学生信息
格式:
表1模型类.objects.filter(外键类属性的名称__表2中字段名=value)
x=Student.objects.filter(class_name__class_name="三班")
注意:
外键类属性的名称__主表中字段名 中间,是两个下划线。
四、逻辑关系
4.1 与
方式一:在同一个filter方法内部,添加多个关键字参数,每个条件为“与”的关系
举例:
查询class_name =2,并且name 中包含 “五”的学生信息。
Student.objects.filter(name__contains="五",class_name=2)
方式二:多次调用fillter方法,QuerySet 链式调用特性
Student.objects.filter(name__contains="五").filter(class_name=2)
4.2 或
可以使用Q查询,实现逻辑关系 【或】,多个Q对象之间 用“|” 实现【或】关系
查询class_name =2,或者name 中包含 “红”的学生信息。
需要提前引入
from django.db.models import Q
Student.objects.filter(Q(name__contains="红") | Q(class_name=2))
4.3 查询排序
排序对象:
只针对QuserSet 查询集或者mannager对象
1、默认ASC升序
QuerySet对象.order_by(“字段名”)
举例,查询name中包含“红”的学生信息,按照 student_id 升序排序
Student.objects.filter(name__contains="红").order_by("student_id")
2、降序排序DESC
在字段名称前加“-”,则为降序
Student.objects.filter(name__contains="红").order_by("-student_id")
上一章:
django ORM框架 第二章 表与表的关系&关联表_做测试的喵酱的博客-CSDN博客