django中的几个表关系的查询

一对一、一对多、多对多的区分:一对一:子表从母表中选出一条数据一一对应,母表中选出来一条就少一条,子表不可以再选择母表中已被选择的那条数据一对多:子表从母表中选出一条数据一一对应,但母表的这条数据还可以被其他子表数据选择多对多总结:比如有多个孩子,和多种颜色、每个孩子可以喜欢多种颜色,一种颜色可以被多个孩子喜欢,对于双向均是可以有多个选择。含有关系字段的表称为子表,被关联的表称之为母表。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)
 
反向查询的三种方式@通过外键母表查询子表,跟一对一关系的查询不同,因为母表为多,不能像一对一一样通过.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(子表外键字段=母表主键对象),此处和一对多略有不同,是子表外键字段而不是外键字段_母表主键
 
 
 
posted @ 2019-07-18 19:55  FFLYY  阅读(227)  评论(0编辑  收藏  举报