JobPlus知识库 IT DBA 文章
django中的几个表关系的查询

一对一、一对多、多对多的区分:

一对一:子表从母表中选出一条数据一一对应,母表中选出来一条就少一条,子表不可以再选择母表中已被选择的那条数据

一对多:子表从母表中选出一条数据一一对应,但母表的这条数据还可以被其他子表数据选择

多对多总结:比如有多个孩子,和多种颜色、每个孩子可以喜欢多种颜色,一种颜色可以被多个孩子喜欢,对于双向均是可以有多个选择。

含有关系字段的表称为子表,被关联的表称之为母表。

OneToOneField:

一对一关系,可将关系字段定义在任意一方。

正向查询即从字表查询母表,由两种格式为:

  1. class person(models.Model):

  2. isMarryed = models.BooleanField(default=True,verbose_name='婚否')

  3. education = models.CharField(max_length=10,verbose_name='学历')

  4. class idCard(models.Model):

  5. countNum = models.IntegerField(default='000000',verbose_name='编号')

  6. name = models.CharField(max_length=20,verbose_name='姓名')

  7. gender = models.BooleanField(default=True,verbose_name='性别')

  8. #只有null=True被设置时,on_delete=models.SET_NULL才能被设置成功

  9. 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;

子表对象.母表表名的小写.母表字段名

  1. class person(models.Model):

  2. isMarryed = models.BooleanField(default=True,verbose_name='婚否')

  3. education = models.CharField(max_length=10,verbose_name='学历')

  4. class idCard(models.Model):

  5. countNum = models.IntegerField(default='000000',verbose_name='编号')

  6. name = models.CharField(max_length=20,verbose_name='姓名')

  7. gender = models.BooleanField(default=True,verbose_name='性别')

  8. #只有null=True被设置时,on_delete=models.SET_NULL才能被设置成功

  9. person = models.OneToOneField(person,on_delete=models.SET_NULL,null=True)

  1. #正向查询

  2. def query(request):

  3. ids = idCard.objects.filter(id=1).first()

  4. info = ids.person.education

  5. ids.person.education = '幼儿园'

  6. ids.person.save()

  7. return HttpResponse(info)

  8. #反向查询

  9. def query1(request):

  10. persons = person.objects.get(id=1)

  11. fuck = persons.idcard.name

  12. return HttpResponse(fuck)

Foreignkey:

一对多关系,将关系字段定义在多方。

正向查询的两种方式:

  1. class className(models.Model):

  2. classNum = models.IntegerField(verbose_name='班级名')

  3. teacher = models.CharField(max_length=20,null=False)

  4. class student(models.Model):

  5. stuId = models.ImageField()

  6. stuName = models.CharField(max_length=20)

  7. inClass = models.ForeignKey(className,on_delete=models.DO_NOTHING)

@通过子表查询母表,子表对象.母表表名的小写.母表字段名,student.objects.get(stuName='锤子'.inClass.teacher;

@通过母表入手,母表.objects.get(子表名小写__子表字段=‘xxx.母表字段名,

className.objects.get(student__stuName='锤子').teacher

  1. #一对多   正向查询

  2. def query2(request):

  3. '''

  4. teacherName = student.objects.get(stuName='罗程')

  5. teacherName = teacherName.inClass.teacher

  6. '''

  7. teacherName = className.objects.get(student__stuName='锤子').teacher

  8. 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)

  1. #一对多   正向查询

  2. def query2(request):

  3. '''

  4. teacherName = student.objects.get(stuName='罗程')

  5. teacherName = teacherName.inClass.teacher

  6. '''

  7. teacherName = className.objects.get(student__stuName='锤子').teacher

  8. return HttpResponse(teacherName)

  9. #反向查询

  10. def query3(request):

  11. '''

  12. 常规写法

  13. fclass = className.objects.filter(id=1).first()

  14. fclass = fclass.student_set.all()

  15. for i in fclass:

  16. print(i.stuName)

  17. return HttpResponse(fclass)

  18. '''

  19. #fclass = student.objects.filter(inClass=1)

  20. #fclass = student.objects.filter(inClass=className.objects.get(id=1))

  21. #fclass = student.objects.filter(inClass__teacher='苍井空')

  22. fclass = student.objects.filter(inClass__id=1)

  23. for i in fclass:

  24. print(i.stuName)

  25. return HttpResponse('1111')


  1. class Colors(models.Model):

  2.     colors=models.CharField(max_length=10) #蓝色

  3.     def __str__(self):

  4.         return self.colors

  5. class Child(models.Model):

  6.     name=models.CharField(max_length=10)   #姓名  

  7.     favor=models.ManyToManyField('Colors')    #与颜色表为多对多

  1. #多对多子表查询母表,查找小明喜欢哪些颜色--返回:[<Colors: 红>, <Colors: 黄>, <Colors: 蓝>]

  2. #与一对多子表查询母表的形式不同,因为一对多,查询的是母表的“一”;多对多,查询的是母表的“多”

  3. #写法1:

  4. child_obj=models.Child.objects.get(name="小明")  #写法:子表对象.子表多对多字段.过滤条件(all()/filter())

  5. print(child_obj.favor.all())

  6. #写法2,反向从母表入手:

  7. print(models.Colors.objects.filter(child__name="小明")) #母表对象.filter(子表表名小写__子表字段名="过滤条件")

  8. #多对多母表查询子表,查找有哪些人喜欢黄色--返回:[<Child: 小明>, <Child: 丫蛋>]

  9. #与一对多母表查询子表的形式完全一致,因为查到的都是QuerySet,一对多和多对多,都是在查询子表的“多”

  10. #写法1:

  11. color_obj=models.Colors.objects.get(colors="黄")

  12. print(color_obj.child_set.all())

  13. #写法2:

  14. print(models.Child.objects.filter(favor=models.Colors.objects.get(colors="黄")))

  15. #写法2简便写法(推荐):

  16. print(models.Child.objects.filter(favor__colors="黄"))  #写法:filter(子表外键字段__母表字段='过滤条件')

  17. #写法3:

  18. color_id=models.Colors.objects.get(colors="黄").id  #通过母表获取到颜色为红的id

  19. print(models.Child.objects.filter(favor=color_id))  #filter得到QuerySet,写法:filter(子表外键字段=母表主键对象),此处


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
98人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序