zoukankan      html  css  js  c++  java
  • django orm 基于双下划线的跨表查询

    一..基于双下划线的跨表查询(join实现)

    key:正向查询按字段,反向查询按表明小写

    1.一对多跨表查询

    1     查询在跨表中可以有两种方式,正向查询就是关键字段在你要搜索的表,没有关键字段就是反向查询
    2     跨表查询的显著特点是__双下划线,这道题中在你要找到name,但是Book中没有,通过正向查询关键字段+__来
    3     跨表找到name
    4     ret=Book.objects.filter(title="python").values("publish__name")
    5         # print(ret)
    6     ret=Publish.objects.filter(book__title="python").values("name")
    7     print(ret)   <QuerySet [{'name': '云南出版社'}]>
    一对多
    1     2 查询小瑞出版社出版的所有的书籍的名称
    2     这道题中反向解析在出版社开始找,但是条件没有'小瑞',跨表寻找条件,
    3     在filter条件先通过反向查询表名小写__+条件找到
    4     ret=Book.objects.filter(publish__name="小瑞").values("title")
    5     print(ret)
    6     ret=Publish.objects.filter(name="小瑞").values("book__title")
    7     print(ret)<QuerySet [{'book__title': 'linux'}, {'book__title': 'css'}]>
    一对多反向跨表

    2.多对多

    1     3 查询python这本书籍的作者的年龄
    2     在多对多的环境下,和一对多查询一样,是因为django是在太过强大,通过字段和表名小写
    3     将多对多关系的三张表统统间接在一起,各取所需,
    4     ret=Book.objects.filter(title="linux").values("authors__age")
    5     print(ret)<QuerySet [{'authors__age': 18}, {'authors__age': 25}]>
    6     ret=Author.objects.filter(book__title="linux").values("age")
    7     print(ret)
    多对多
    1    4 查询alex出版过的所有的书籍名称
    2     ret=Author.objects.filter(name="alex").values("book__title")
    3     print(ret)<QuerySet [{'book__title': 'python5'}, {'book__title': 'linux'}, {'book__title': 'css'}]>
    4     ret=Book.objects.filter(authors__name="alex").values("title")
    5     print(ret)
    多对多反向

    3.一对一

     1     5 查询alex的手机号
     2     ret=Author.objects.filter(name="alex").values("ad__tel")
     3     print(ret)<QuerySet [{'ad__tel': 123}]>
     4     ret=AuthorDetail.objects.filter(author__name="alex").values("tel")
     5     print(ret)
     6     6 查询手机号为110的作者的名字
     7     ret=AuthorDetail.objects.filter(tel="234").values("author__name")
     8     print(ret)<QuerySet [{'author__name': 'egon'}]>
     9     ret=Author.objects.filter(ad__tel="234").values("name")
    10     print(ret)
    一对一

    聪明的你不难发现只要掌握了查询方式key,都是一样的

    4.多个表单连续查询

    1   1.查询小瑞出版社出版过的所有书籍的名字以及作者的姓名
    2     这里可以通过表之间的关系逐步连成一张大表查询,注意的是连接时
    3     是正向还是反向查询
    4     ret=Publish.objects.filter(name="小瑞").values("book__title","book__authors__name")
    5     print(ret)<QuerySet [{'book__title': 'linux', 'book__authors__name': 'alex'}, {'book__title': 'css', 'book__authors__name': 'alex'}, {'book__title': 'linux', 'book__authors__name': 'egon'}, {'book__title': 'css', 'book__authors__name': 'egon'}]>
    6     ret=Author.objects.filter(book__publish__name="小瑞").values("name","book__title")
    7     print(ret)
    多次跨表查询

    二>

    聚合,分组

    聚合与分组的区别是,聚合显示的是 aggregate 后面的结果,如

    而分组后的结果往往是以all() 分组的话 ,前面不写values().如

    一个个queryset对象列表,,需要values 来取出接轨

    要是在values为条件分组的话,显示的是values()里面的条件和annotate后面的函数 组成键值对

    要是在条件的后面写上了values(),按照具体要求分组,则是会是按你的要求分组

    1.聚合

     1     #聚合
     2     #查询所有作者的平均年龄
     3     #聚合分组前一定要引入模块,才会有效
     4     from django.db.models import Avg,Max,Sum,Min,Count
     5     # 查询坐着的平均年龄
     6     # ret=Author.objects.aggregate(Avg("age"))
     7     # print(ret){'age__avg': 21.6667}
     8     # # 查询所有书籍的个数
     9     # ret=Book.objects.aggregate(c=Count("title"))
    10     # print(ret) {'c': 4}
    聚合

    2.分组

    1  单表分组查询
    2 这里的结果就是一个由title 与 c 组成的键值对
    3     查询书籍表每一个出版社id以及对应的书籍个数
    4     ret=Book.objects.values("title").annotate(c=Count(1))
    5     print(ret)<QuerySet [{'title': 'python5', 'c': 1}, {'title': 'python', 'c': 1}, {'title': 'linux', 'c': 1}, {'title': 'css', 'c': 1}]>
    6     # 查询每一个部门的名称以及对应员工的平均薪水
    7     ret=Author.objects.values("name").annotate(a=Avg("age"))
    8     print(ret)<Que
    单表分组
     1 跨表分组查询
     2     在跨表分组中,可以在函数中使用跨表,也可以在后面的values()进行取键值对的跨表,和跨表查询一样
     3     查询每一个出版社的名称以及对应的书籍平均价格
     4     ret=Publish.objects.annotate(c=Avg("book__price")).values("book__title","book__price","email")
     5     print(ret)<QuerySet [{'book__title': 'python5', 'book__price': Decimal('100.00'), 'email': '234'}, {'book__title': 'python', 'book__price': Decimal('100.00'), 'email': '234'}, {'book__title': 'linux', 'book__price': Decimal('100.00'), 'email': '123'}, {'book__title': 'css', 'book__price': Decimal('150.00'), 'email': '123'}]>
     6     查询每一个作者的名字以及出版的书籍的最高价格
     7     ret=Author.objects.values("name").annotate(c=Max("book__price"))
     8     print(ret)<QuerySet [{'name': 'alex', 'c': Decimal('150.00')}, {'name': 'egon', 'c': Decimal('150.00')}, {'name': 'zero', 'c': None}]>
     9     查询每一个书籍的名称以及对应的作者的个数
    10     ret=Book.objects.values("pk").annotate(c=Count("authors"))
    11     print(ret)
    12     ret=Book.objects.annotate(c=Count("authors"))
    13     print(ret)
    14     4 查询作者数不止一个的书籍名称以及作者个数
    15     ret=Author.objects.annotate(c=Count("book__title")).filter(c__gt=1).values("book__title","c")
    16     print(ret)
    17     ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c")
    18     print(ret)<QuerySet [{'title': 'python5', 'c': 2}, {'title': 'linux', 'c': 2}, {'title': 'css', 'c': 2}]>
    19     5 根据一本图书作者数量的多少对查询集 QuerySet进行排序
    20     ret=Book.objects.annotate(c=Count("authors__name")).order_by("c")
    21     print(ret)<QuerySet [<Book: Book object (2)>, <Book: Book object (1)>, <Book: Book object (4)>, <Book: Book object (3)>]>
    22     6 统计每一本以py开头的书籍的名称以及作者个数
    23     ret=Book.objects.annotate(c=Count("authors__name")).filter(title__startswith="py").values("title")
    24     print(ret)
    多表分组

    3.F与Q

    F是在filter中,比如说进行两个变量的比较,之类的用F函数

    在这之前需要引入函数

    from django.db.models import F,Q
     1     from django.db.models import F,Q
     2     # 查询评论数大于100的所有的书籍名称
     3     ret=Book.objects.filter(count_num__gt=1000).values("title")
     4     print(ret)
     5     # 查询评论数大于2倍点赞数的所有的书籍名称
     6     ret=Book.objects.filter(count_num__gt=F("poll_num"))
     7     print(ret)
     8     # 查询评论数大于2倍点赞数的所有的书籍名称
     9     Book.objects.filter(count_num__gt=F("poll_num")*2)
    10     ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000))
    11     print(ret)
    F函数

    Q函数则是进行条件的判断时,比如价格>100或者地址在xxx"",通过比较的函数对比出来

    & 和  |或 ~非

    ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000))
    print(ret)
  • 相关阅读:
    iframe中的页面如何触发父页面事件
    js获取gridview的值
    不出现重复数字,带干扰的验证码
    文本框内不允许输入字母
    后台调用前台JS方法
    在后台得到前台元素,给元素改变属性值或添加属性
    C#常见面试题
    Flex代码生成器 (FCG)
    c#(WinForm)遍历局域网计算机(电脑)获取IP和计算机名称
    VisualSVN Server + Tortoise SVN 使用教程(补充版)
  • 原文地址:https://www.cnblogs.com/zhangqing979797/p/9867501.html
Copyright © 2011-2022 走看看