zoukankan      html  css  js  c++  java
  • Django关联关系查询

    一对一Model ,有外键即设置关联关系的一方为从表,从表查主表为正向查询,反之。这里护照为从表,人为主表。

    class Passport(models.Model): # 护照(从表)
    note = models.CharField(max_length=20)
    person = models.OneToOneField(to="Person",on_delete=models.CASCADE,null=True) #关系属性
    class Meta:
    db_table="t_passport"

    class Person(models.Model): # 人(主表)
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    class Meta:
    db_table="t_person"
    注:不需要手动设置 person字段唯一,自动会设置为唯一

    一对一 一个人一本护照

    # 1.只查 单方数据 (与单表数据查询一致)
    # 只查人的信息
    ps = Person.objects.filter(name='Tom').values() # 自己查自己
    print(ps)
    # 只查 护照的信息
    p1 = Passport.objects.all().values()
    print(p1)
    ps = Person.objects.filter(passport='1').values()
    print(ps)

    # 2.通过一方查另一方数据 (先获取一方数据,再通过它查询另一方)
    # 查询 名字为tom的护照信息
    p1 = Person.objects.get(name='Tom')
    print(p1.passport.note) #反向查询 基于对象 类名小写
    # 查询护照为美国的人的信息
    ps = Passport.objects.get(note='美国')
    print(ps.per_id, ps.per.name,ps.per.age) #正向查询 基于对象 直接调用外键

    # 3.通过一方 查另一方 (查询条件是对方)
    # 查询名字为tom的护照信息
    p1 = Passport.objects.filter(per__name='Tom').values() #正向查询 基于字段 外键__字段
    print(p1)
    # 查询护照为美国的人的信息
    p1 = Person.objects.filter(passport__note='美国').values() #反向查询 基于字段 类小写__字段
    print(p1)
    print(Person.objects.filter(passport__note='美国')) # QuerySet集合对象

    # 4.保留双方数据 ()
    # 查询名字为Tom的人信息 和 护照的信息
    p1 = Person.objects.filter(name='Tom').values('name','age','passport__note') #反向查询 基于字段 类小写__字段
    print(p1)
    p1 = Passport.objects.filter(per__name='Tom').values('note','per__name','per__age','per_id') #正向查询 基于字段 外键__字段
    print(p1)

    一对一查询总结:

    正向查询时,基于对象,对象.直接调用外键;基于字段 外键__字段

    反向查询时,基于对象,对象.类名小写;基于字段 类小写__字段

    感觉从表和主表查起来差不多。

    一对多Model 货物为从表,种类为主表

    class Category(models.Model): #种类(主表)
    title = models.CharField(max_length=20)
    note = models.CharField(max_length=20)
    class Meta:
    db_table="t_category"

    class Goods(models.Model): #货物(从表)
    title = models.CharField(max_length=20,unique=True)
    price = models.FloatField()
    cate = models.ForeignKey(to=Category,on_delete=models.CASCADE) #关系属性 主表删除后,从表中使用主表中数据的也会跟随一起删除
    class Meta:
    db_table = "t_goods"

    # 1对多关系 Category(1):没有关系属性 Goods(*):其中有关系属性cate
    # 一对多 查询 category主表 goods从表

    # 1.只查询一方数据
    # 只查 主表
    c1 = Category.objects.filter(name='服装').values()
    print(c1)
    g1 = Goods.objects.filter(price=5000).values()
    print(g1)

    # 2.通过一方查询另一方 (先查询到一方数据,再通过它查询另一方)
    # 查询服装类别为男装的 商品名称
    c1 = Category.objects.get(name='服装')
    print(c1.goods_set) # 查询也是一个集合 #反向查询 基于对象 对象.表名_set
    print(c1.goods_set.all()) # 查询也是一个集合
    # 查询 商品沙发所属的类别
    g1 = Goods.objects.get(title='沙发')
    print(g1.cate.name, g1.cate.note) #正向查询 基于对象 对象.外键.字段

    # 3.通过一方查询另一方(查询条件是另一方)
    # 查询 床 商品的 类别信息
    c1 = Category.objects.filter(goods__title='床').values() #反向查询 基于字段 表名__字段
    print(c1)
    # 查询分类为 家居 类别的 商品信息
    g1 = Goods.objects.filter(cate__name='家居').values() #正向查询 基于字段 外键__字段
    print(g1)

    # 4.保留双方数据
    # 查询商品名称为 电视 的分类信息 和 商品信息
    c1 = Category.objects.filter(goods__title='电视').values('name','note','goods__title','goods__price') #反向查询 基于字段 表名__字段
    print(c1)
    # 查询商品价格大于5000的商品的分类信息
    c1 = Category.objects.filter(goods__price__gt=5000) #反向查询 基于字段 表名__字段
    print(c1)
    print(set(c1))

    #注意在进行联合查询时,可能会由重复数据出现,解决:
    list(set(Category.objects.filter(goods__price__gt=200)))

    一对多总结:

    正向查询时,基于对象,对象.外键.字段;基于字段,外键__字段

    反向查询时,基于对象,对象.表名_set;基于字段,表名__字段

    多对多Model

    class Student(models.Model): #学生(主表)
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    class Meta:
    db_table="t_student"

    class Course(models.Model): #课程(从表)
    title = models.CharField(max_length=30)
    expire = models.SmallIntegerField()
    stu = models.ManyToManyField(to=Student) #关系属性
    class Meta:
    db_table="t_course"

    # 多对多关系 Course:有对方关系属性students, Student:没有对方关系属性

    # 1.只查询一方
    # 查询学生 linda 学生信息
    s1 = Student.objects.filter(name='Linda').values()
    print(s1)
    # 查询mysql课程信息
    c1 = Course.objects.filter(title__icontains='MYSQL').values()
    print(c1)

    # 2.查询一方,通过它查询另一方
    # 查询 学习mysql的学生信息
    c1 = Course.objects.get(title='DJANGO')
    print(c1.stu.all()) #正向查询 基于对象 对象.外键
    # 查询 学生 linda 课程信息
    s1 = Student.objects.get(name='Linda')
    print(s1.course_set.all()) #反向查询 基于对象 对象.表名_set
    print(s1.course_set.values())

    # 3.通过一方 查询 另一方 (查询条件为对方)
    # 查询 学生 linda 课程信息
    c1 = Course.objects.filter(stu__name='Linda').values() #正向查询 基于字段 外键__字段
    print(c1)
    # 查询 学习mysql的学生信息
    s1 = Student.objects.filter(course__title='PYTHON').values() #反向查询 基于字段 表名__字段
    print(s1)


    # 4.保留双方数据
    # 查询学习django的学生信息 和 课程信息
    s1 = Student.objects.filter(course__title='DJANGO').values('name','age','course__title','course__expire') #反向查询 基于字段 表名__字段
    print(s1)
    # 查询jack学习的课程信息 和 学生信息
    c1 = Course.objects.filter(stu__name='Jack').values('title','expire','stu__age','stu__name') #正向查询 基于字段 外键__字段
    print(c1)


    #关联查询
    Student.objects.filter(course__title__contains="h") #标题中含有"h"的课程中的学生 #反向查询 基于字段 表名__字段
    Course.objects.filter(stu__name="zzz") #姓名为zzz的学生参加的课程 #正向查询 基于字段 外键__字段
    Course.objects.filter(stu__age__gt=18) #年龄大于18的学生参加的课程 #正向查询 基于字段 外键__字段
    坑:不能查具体某个字段

    多对多总结:

    正向查询时,基于对象,对象.外键;基于字段,外键__字段

    反向查询时,基于对象,对象.表名_set;基于字段,表名__字段

    最后3个总结写在一起比较:

    一对一查询总结:

    正向查询时,基于对象,对象.直接调用外键;基于字段 外键__字段

    反向查询时,基于对象,对象.类名小写;基于字段 类小写__字段

    一对多总结:

    正向查询时,基于对象,对象.外键.字段;基于字段,外键__字段

    反向查询时,基于对象,对象.表名_set;基于字段,表名__字段

    多对多总结:

    正向查询时,基于对象,对象.外键;基于字段,外键__字段

    反向查询时,基于对象,对象.表名_set;基于字段,表名__字段

    最后总结,

    基于对象的情况下,正向查询时基本一致,直接调用外键就好;反向查询时一对多和多对多,需要对象.表名_set调用。

    基于字段的情况下,正向查询时,外键__字段;反向查询时,表名__字段。一对一可能为类名小写__字段。

  • 相关阅读:
    14.会场安排问题(L4)
    图形化调试工具DDD
    sking
    全排列
    DNS
    一种排序
    多边形重心问题
    街区最短路径问题
    Fibonacci数
    python url解析
  • 原文地址:https://www.cnblogs.com/lag1/p/13821461.html
Copyright © 2011-2022 走看看