一对一、一对多、多对多的区分:
一对一:子表从母表中选出一条数据一一对应,母表中选出来一条就少一条,子表不可以再选择母表中已被选择的那条数据
一对多:子表从母表中选出一条数据一一对应,但母表的这条数据还可以被其他子表数据选择
多对多总结:比如有多个孩子,和多种颜色、每个孩子可以喜欢多种颜色,一种颜色可以被多个孩子喜欢,对于双向均是可以有多个选择。
含有关系字段的表称为子表,被关联的表称之为母表。
OneToOneField:
一对一关系,可将关系字段定义在任意一方。
正向查询即从字表查询母表,由两种格式为:
class person(models.Model):
isMarryed = models.BooleanField(default=True,verbose_name='婚否')
education = models.CharField(max_length=10,verbose_name='学历')
class idCard(models.Model):
countNum = models.IntegerField(default='000000',verbose_name='编号')
name = models.CharField(max_length=20,verbose_name='姓名')
gender = models.BooleanField(default=True,verbose_name='性别')
#只有null=True被设置时,on_delete=models.SET_NULL才能被设置成功
person = models.OneToOneField(person,on_delete=models.SET_NULL,null=True)
@从子表查询:子表对象.母表表名的小写.母表字段名,idCard.objects.get(id=1).person.education;
@从母表查询:通过子表查询母表,但形式上是从母表对象自身直接获取字段,写法是母表.objects.get(子表名小写__子表字段=‘xxx').母表字段名,person.objects.get(idCard__id=1).education;
反向查询即从母表查询子表,有两种格式:
@从母表查询:母表对象.子表表名小写.子表字段名,person.objects.get(id=1).idcard.name;
@从子表查询,通过母表查询子表,但形式上是从子表对象自身直接获取字段,子表.objects.get(一对一的子表字段__母表字段=‘xxx').子表字段,idCard.objects.get(person__education='初中').name;
子表对象.母表表名的小写.母表字段名
class person(models.Model):
isMarryed = models.BooleanField(default=True,verbose_name='婚否')
education = models.CharField(max_length=10,verbose_name='学历')
class idCard(models.Model):
countNum = models.IntegerField(default='000000',verbose_name='编号')
name = models.CharField(max_length=20,verbose_name='姓名')
gender = models.BooleanField(default=True,verbose_name='性别')
#只有null=True被设置时,on_delete=models.SET_NULL才能被设置成功
person = models.OneToOneField(person,on_delete=models.SET_NULL,null=True)
#正向查询
def query(request):
ids = idCard.objects.filter(id=1).first()
info = ids.person.education
ids.person.education = '幼儿园'
ids.person.save()
return HttpResponse(info)
#反向查询
def query1(request):
persons = person.objects.get(id=1)
fuck = persons.idcard.name
return HttpResponse(fuck)
Foreignkey:
一对多关系,将关系字段定义在多方。
正向查询的两种方式:
class className(models.Model):
classNum = models.IntegerField(verbose_name='班级名')
teacher = models.CharField(max_length=20,null=False)
class student(models.Model):
stuId = models.ImageField()
stuName = models.CharField(max_length=20)
inClass = models.ForeignKey(className,on_delete=models.DO_NOTHING)
@通过子表查询母表,子表对象.母表表名的小写.母表字段名,student.objects.get(stuName='锤子'.inClass.teacher;
@通过母表入手,母表.objects.get(子表名小写__子表字段=‘xxx.母表字段名,
className.objects.get(student__stuName='锤子').teacher
#一对多 正向查询
def query2(request):
'''
teacherName = student.objects.get(stuName='罗程')
teacherName = teacherName.inClass.teacher
'''
teacherName = className.objects.get(student__stuName='锤子').teacher
return HttpResponse(teacherName)
反向查询的三种方式
@通过外键母表查询子表,跟一对一关系的查询不同,因为母表为多,不能像一对一一样通过.ger().子表.子表字段来获取,母表对象.子表名的小写.all()
fclass = className.objects.filter(id=1).first().student_set.all()【得到的是一个queryset】
@fclass = student.objects.filter(inClass=className.objects.get(id=1))--->简便写法:
fclass = student.objects.filter(inClass__teacher='苍井空')【filter(子表外键字段__母表字段='过滤条件')】
@通过子表入手,子表表名.objects.filter(子表外键字段_母表主键=母表主键对象),
fclass = student.objects.filter(inClass__id=1)
#一对多 正向查询
def query2(request):
'''
teacherName = student.objects.get(stuName='罗程')
teacherName = teacherName.inClass.teacher
'''
teacherName = className.objects.get(student__stuName='锤子').teacher
return HttpResponse(teacherName)
#反向查询
def query3(request):
'''
常规写法
fclass = className.objects.filter(id=1).first()
fclass = fclass.student_set.all()
for i in fclass:
print(i.stuName)
return HttpResponse(fclass)
'''
#fclass = student.objects.filter(inClass=1)
#fclass = student.objects.filter(inClass=className.objects.get(id=1))
#fclass = student.objects.filter(inClass__teacher='苍井空')
fclass = student.objects.filter(inClass__id=1)
for i in fclass:
print(i.stuName)
return HttpResponse('1111')
class Colors(models.Model):
colors=models.CharField(max_length=10) #蓝色
def __str__(self):
return self.colors
class Child(models.Model):
name=models.CharField(max_length=10) #姓名
favor=models.ManyToManyField('Colors') #与颜色表为多对多
#多对多子表查询母表,查找小明喜欢哪些颜色--返回:[<Colors: 红>, <Colors: 黄>, <Colors: 蓝>]
#与一对多子表查询母表的形式不同,因为一对多,查询的是母表的“一”;多对多,查询的是母表的“多”
#写法1:
child_obj=models.Child.objects.get(name="小明") #写法:子表对象.子表多对多字段.过滤条件(all()/filter())
print(child_obj.favor.all())
#写法2,反向从母表入手:
print(models.Colors.objects.filter(child__name="小明")) #母表对象.filter(子表表名小写__子表字段名="过滤条件")
#多对多母表查询子表,查找有哪些人喜欢黄色--返回:[<Child: 小明>, <Child: 丫蛋>]
#与一对多母表查询子表的形式完全一致,因为查到的都是QuerySet,一对多和多对多,都是在查询子表的“多”
#写法1:
color_obj=models.Colors.objects.get(colors="黄")
print(color_obj.child_set.all())
#写法2:
print(models.Child.objects.filter(favor=models.Colors.objects.get(colors="黄")))
#写法2简便写法(推荐):
print(models.Child.objects.filter(favor__colors="黄")) #写法:filter(子表外键字段__母表字段='过滤条件')
#写法3:
color_id=models.Colors.objects.get(colors="黄").id #通过母表获取到颜色为红的id
print(models.Child.objects.filter(favor=color_id)) #filter得到QuerySet,写法:filter(子表外键字段=母表主键对象),此处
登录 | 立即注册