ORM跨表查询和分组查询---二次剖析

阅读目录(Content)

创建表(建立模型)

实例:我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名和年龄。

作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)

出版商模型:出版商有名称,所在城市以及email。

书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。

模型建立如下:

  1. class Author(models.Model):
  2. nid = models.AutoField(primary_key=True)
  3. name=models.CharField( max_length=)
  4. age=models.IntegerField()
  5.  
  6. # 与AuthorDetail建立一对一的关系
  7. authorDetail=models.OneToOneField(to="AuthorDetail")
  8.  
  9. class AuthorDetail(models.Model):
  10.  
  11. nid = models.AutoField(primary_key=True)
  12. birthday=models.DateField()
  13. telephone=models.BigIntegerField()
  14. addr=models.CharField( max_length=)
  15.  
  16. class Publish(models.Model):
  17. nid = models.AutoField(primary_key=True)
  18. name=models.CharField( max_length=)
  19. city=models.CharField( max_length=)
  20. email=models.EmailField()
  21.  
  22. class Book(models.Model):
  23.  
  24. nid = models.AutoField(primary_key=True)
  25. title = models.CharField( max_length=)
  26. publishDate=models.DateField()
  27. price=models.DecimalField(max_digits=,decimal_places=)
  28. keepNum=models.IntegerField()<br> commentNum=models.IntegerField()
  29.  
  30. # 与Publish建立一对多的关系,外键字段建立在多的一方
  31. publish=models.ForeignKey(to="Publish",to_field="nid")
  32.  
  33. # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
  34. authors=models.ManyToManyField(to='Author')  

基于对象的跨表查询

  1. ''''
    一对多:
    正向查询按字段
    Book--------------->Publish
    <---------------
    反向查询按表名小写_set
    '''''

一对多查询(Publish与Book)

正向查询按字段(看class里的publish = models.ForeignKey(to='Publish'))

  1. # () 查询id为2的书籍对应出版社的邮箱
  2. # Book.objects.filter(id=) 是 一个 queryset对象,
  3. obj = Book.objects.filter(id=).first()
  4. # 正向查询按字段
  5. ret= obj.publish.email

  filter 可以换成 get 但是get没有会报错

反向查询(按表名:book_set):

  1. #() 沙河出版社出版过的所有的书籍的名字
  2. obj = Publish.objects.filter(name='沙河出版社').first()
  3. # 出版社找书籍 --反向查找
  4. obj1 = obj.book_set.all().values("name")
  1. '''
    多对多:
    正向查询按字段
    Book--------------->Author
    <---------------
    反向查询按表名小写_set
    反向查询按xxx
    '''

多对多查询 (Author 与 Book)

正向查询(按字段:authors)

  1. #()查询<涉哥开车来造>所有作者的名字
  2.  
  3. obj = Book.objects.filter(name='涉哥开车来造').first()
  4. # 正向查询按字段
  5. ret = obj.author.all().values('name')

反向查询(按表名:book_set)

  1. #() 查询杨刚出版的书籍个数
  2. obj=Author.objects.filter(name='杨刚').first()
  3. # 出版社找书籍 --反向查找
  4. ret = obj.book_set.all().count()

一对一查询(Author 与 AuthorDetail)

  1. '''
    一对一:
    正向查询按字段
    Book--------------->Author
    <---------------
    反向查询按表名小写
  2.  
  3. '''
  1. 正向查询按字段
  1. # (5)查询杨刚的手机号
  2. obj = Author.objects.filter(name='杨刚').first()
  3. # 正向查询按字段
  4. ret = obj.auther_detail.tele
  1. 反向查询按表名小写
  1. #(6) 住在北京的作者的名字
  2.  
  3. obj = AuthorDetail.objects.filter(addr='北京').first()
  4. # 反向查询按表名小写
  5. ret = obj.author.name
  6. print(ret)

注意:

你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Article model 中做一下更改: publish = ForeignKey(Blog, related_name='bookList'),

基于双下划线的跨表查询

Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止

关键点:正向查询按字段,反向查询按表名

  1. # ()查询价格为111的书籍对应出版社的邮箱
  2. obj = Book.objects.filter(price=).values('publish__email')
  3. print(obj)
  1. # () 沙河出版社出版过的所有的书籍的名字
  2. obj1 = Publish.objects.filter(name='沙河出版社').values('book__author__name')
  3. print(obj1)
  1. # ()查询<涉哥开车来造>所有作者的名字
  2. obj2 = Book.objects.filter(name='涉哥开车来造').values('author__name')
  3. print(obj2)
  1. # () 查询杨刚出版的书籍个数
  2. obj3=Author.objects.filter(name='杨刚').values('book__name').count()
  3. print(obj3)
  1. # ()查询杨刚的手机号
  2. obj4 = Author.objects.filter(name='杨刚').values('auther_detail__tele')
  3. print(obj4)
  1. # () 住在北京的作者的名字
  2. obj5 = AuthorDetail.objects.filter(addr='北京').values('author__name')
  3. print(obj5)

分组查询

多表查询

  1. #(1) 每一个出版社的名字以及对应出版书籍个数
  2. obj = Publish.objects.all().annotate(c=Count("book__name")).values("name","c")
  3. print(obj)
  1. # ()查询每一个作者的名字以及对应书籍的平均价格
  2. obj1 = Author.objects.all().annotate(c=Avg('book__price')).values('name','c')
  3. print(obj1)
  1. # ()查询每一本书 的名字以及作者的个数
  2. obj2 = Book.objects.all().annotate(c=Count("author")).values("name","c")
  3. print(obj2)

单表查询

  1. # 单表查询
  2. ret = Book.objects.values("name").annotate(c=Count("*"))
  3. print(ret)

第十七篇 ORM跨表查询和分组查询---二次剖析的更多相关文章

  1. Django【第7篇】:Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)

    django之跨表查询及添加记录 一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many); ...

  2. ORM单表查询,跨表查询,分组查询

    ORM单表查询,跨表查询,分组查询   单表查询之下划线 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值models ...

  3. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  4. Django之ORM跨表操作

    Django之ORM表查询及添加记录 一.创建表 - 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-man ...

  5. 6月21日 Django ORM那些相关操作(表关联、聚合查询和分组查询)

    一.ForeignKey操作 正向查找 对象查找(跨表) 语法: 对象.关联字段.字段   示例: book_obj = models.Book.objects.first() # 第一本书对象 pr ...

  6. 基于对象的跨表查询,多对多查询,多对多操作,聚合查询和分组查询,F查询和Q 查询

    基于对象的跨表查询 一对多查询(班级表和学生表) 表结构创建 class Class(models.Model): id = models.AutoField(primary_key=True) cn ...

  7. Django框架(十)—— 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询、聚合查询、分组查询、F查询与Q查询

    目录 多表操作:增删改,基于对象/双下划线的跨表查询.聚合查询.分组查询.F查询与Q查询 一.创建多表模型 二.一对多增删改表记录 1.一对多添加记录 2.一对多删除记录 3.一对多修改记录 三.一对 ...

  8. Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)

    摘要: 单表查询 多表查询 聚合查询 分组查询 一.Django ORM 常用字段和参数: 常用字段:#AutoFieldint自增列,必须填入参数primary_key = True,当model中 ...

  9. Django进阶Model篇007 - 聚集查询和分组查询

    接着前面的例子,举例聚集查询和分组查询例子如下: 1.查询人民邮电出版社出了多少本书 >>> Book.objects.filter(publisher__name='人民邮电出版社 ...

随机推荐

  1. Laradock 如何通过 ssh 方式连接到 workspace

    用 docker-compose exec workspace bash 方式可以进入容器,但是还是在 xshell 终端连接比较方便.   在网上也没找到方法,其实可以通过密钥的方式连接.记录一下仅 ...

  2. JS之如何将Promise.then的值直接return出来

    不可能直接将Promise.then的值直接return出来,只能return出Promise对象,然后继续.then去操作异步请求得到的值.

  3. 第3节 storm高级应用:6、定时器任务;7、与jdbc的整合使用;8、与jdbc整合打包集群运行

    ======================================= 5.storm的定时器以及与mysql的整合使用 功能需求:实现每五秒钟打印出当前时间,并将发送出来的数据存入到mysq ...

  4. ch13 事件(思维导图)

  5. Data Cleaning_Chicago Air-quality Case_TBC!!!

     

  6. css限制文字显示字数长度,超出部分自动用省略号显示,防止溢出到第二行

    为了保证页面的整洁美观,在很多的时候,我们常需要隐藏超出长度的文字.这在列表条目,题目,名称等地方常用到. 效果如下: 未限制显示长度,如果超出了会溢出到第二行里.严重影响用户体验和显示效果. 我们在 ...

  7. SimpleAuthenticationInfo

    public SimpleAuthenticationInfo(Object principal, Object hashedCredentials, ByteSource credentialsSa ...

  8. 第3节 sqoop:7、通过java代码远程连接linux执行shell命令

    数据库的数据同步软件sqoop 数据同步 关系型数据库到大数据平台 任务:sqoop 是批量导入数据太慢,如何做到实时的数据同步 实时的数据同步工具: canal 阿里开源的一个数据库数据实时同步的软 ...

  9. IDEA快速升级模块版本号

    使用场景 一个多模块的项目中,在功能用重大更新后,需要升级版本号,如果不使用工具,需要手动更改每个pom.xml文件,而使用工具,就可以非常快速的完成版本号的更改. 基本步骤 0.  idea执行ma ...

  10. 吴裕雄--天生自然java开发常用类库学习笔记:Map接口

    import java.util.HashMap ; import java.util.Map ; public class HashMapDemo01{ public static void mai ...