• ORM的查询


    基于对象的跨表查询(sql里的子查询)(重点)

    一对多查询:

    Book(有外键)--------------->Publish     属于正向查询  按book表里的字段book.publish

    Book(含外键)<---------------Publish    是反向查询   按表名小写_set.all()

    正向查询      例如:查python这本书的出版社的名字和邮箱    

    book=Book.objects.filter(title="python").first()   #拿到对象,  对象.属性才可以获取值

    print(book.publish.name)

    print(book.publish.email)

    反向查询   例如:查苹果出版社 出版的所有书籍的名字

    pub_obj=Publish.objects.get(name="苹果出版社")

    print(pub_obj.book_set.all())  #  print(pub_obj.book_set) 出版社找书, 因为出版过很多书,所以用 _set,   .all()是找出所有的书

    多对多查询:

    Book(有外键)--------------->Author     正向查询  按book表里的字段book.authors.all() 得到的是一个集合

    Book(含外键)<---------------Publish    反向查询   按表名小写_set.all()

    正向查询   例如找python作者的年龄

    book=Book.objects.filter(title="python").first()    #拿到python这本书

    ret = book.authors.all() # 拿到与这本书关联的所有作者queryset

    ret2 = book.authors.all().value("age")

    print(ret2)

    反向查询    例如找alex出版过的书

    alex=Author.objects.filter("name"="Alex").first()  #获取到alex对象  filter得到的是queryset   .first()得到的是对象

    print(alex.book_set.all())   

    一对一查询

    Author--------------->AuthorDetail     正向查询  按字段   alex.ad(Author表里的字段)

    Author<---------------AuthorDetail     反向查询   按表名  ad.author(表名)

    正向查询   例如:查询alex的手机号

    alex=Author.objects.filter("name"="alex").first()

    print(alex.ad.tel)

    反向查询   例如:查手机号是110的用户名

    ad=AuthorDetail.objects.filter(tel=110).first()

    print(ad.author.name)

    -------------------------------------------------------------------------------------------------

    双下划线的跨表查询(基于sql中的join实现 ) (重点)

    规则:正向查询按字段    反向查询按表名的小写    

    不管以哪张表为基表,   写在最前面的过滤条件是不变的, 变的是过滤条件的书写方式, 就是按照上面的规则拼写

    一对多

    例1: 查python的出版社的名字和邮箱

    以Book为基表   从Book 往Publish方向找   是正向查询

    ret=Book.objects.filter(title="python").values("publish__name") #在values这开始跨表 告诉ORM的book表拼publish表

    print(ret)

    以Publish为基表  查出版python的出版社名字

    ret=Publish.objects.filter(book__title="python").values("name")

     #book__title="python"      title不在基表Publish中 所以先拼表book(title字段在book中)  再反向拼表按表名小写book__title    

    #values("name")      name是基表Publish自己的字段可以直接使用

    例2: 查苹果出版社出版的所有的书的名字

    以Book为基表 是正向查询

    ret=Book.objects.filter(pubish__name="苹果出版社").values("title")

    print(ret)

    #苹果出版社不在基表Book里面,所以要先到Publish中把name="苹果出版社"的过滤出来

    #title是Book基表自己的字段

    以Publish为基表  反向查询

    ret=Publish.objects.filter(name="苹果出版社").values("book__title"")

    print(ret)

    #name="苹果出版社"     name在基表Pubish里面,所以直接使用name字段

    #title 不在基表Publish里面,   所以要先找到Book表 (通过表名小写的方式), 再__title

    多对多

    例1: 查python这本书作者的名字

    以Book为基表      正查按字段

    ret=Book.objects.filter(title="python").values("author__age")

    print(ret)

    #author      Book拼关联的author表   把三张表拼在一起

    #title在基表Book里面     

    以Author为基表

    ret=Author.objects.filter(book__title="python").values("age")

    print(ret)

    例2:  查alex出版过的书    

    以Book表为基表

    ret=Book.objects.filter(authors__name="alex").values("title")  

    print(ret)  # [{ "title"=python }]

    以Author表为基表

    ret=Author.objects.filter(name="alex").values("book__title")

    print(ret)  # [{ "book__title"=python }]        对比一下两种方式的查询结果

    一对一

    例1:  查alex的tel

    以Author为基表   正向查询条件按字段

    ret=Author.objects.filter(name="alex").values("ad__tel")

    print(ret)

    以AuthorDetail为基表

    ret=AuthorDetail.objects.filter(authors__name="Alex").values("tel")

    print(ret)

    例2:手机号为110的作者的名字

    以AuthorDetail为基表  

    ret=AuthorDetail.objects.filter(tel="110").values("author__name")

    print(ret)

    # tel在基表里面,所以直接查询.    

    # name不在基表里面,所以要加表名小写author__name

    以Author为基表

    ret=Author.objects.filter("ad__tel=110").values("name")

    print(ret)

    --------------------------------------------------------------------------------------------

    连续跨表查询

    例1:   人民出版社出版过所有书的名称以及作者的名字 (会用到Publish   Book   Author三张表)

    以Publish为基表

    ret=Publish.objects.filter(name="人民出版社").values("book__title","book__authors__name")

    print(ret)

    #name在基表的字段里, title和name需要用所在的表名小写连接起来再查询

    #站在基表的角度跨表

    以Book为基表

    ret=Book.objects.filter(publish__name="人民出版社").values("title","author__name")

    print(ret)

    例2:  以手机号110开头的作者出版过的所有的 书的名称以及出版社名称(会用AD  Author  Book  Publish四张表 )

    以Author为基表

    ret=Author.objects.filter(ad__tel__startswith=110).values("book__title","book__publish__name")

    print(ret)

    #没有在基表里的查询字段都需要用加引号

    ------------------------------------------------------------------------------------------

    聚合  分组查询

    from django.db.models import Avg, Sum, Max, Min, Count

    聚合

    例1:  查询所有书籍的平均价

    ret=Book.objects.all().aggregate(priceAvg=Avg("price"))

    print(ret)   #{"priceAvg":123}

    例2:  查有多少本书

    ret=Book.objects.all().aggreagte(c=Count("nid"))

    print(ret)   #{"c":4}

    分组               以哪个字段分组 就把哪个字段放在values()里

    单表分组查询

    例1:  查询Book表中每个出版社的id以及对应出版书的个数

    ret=Book.objects.values("title").annotate()   

    #按照title分组的group by          values里面是分组的字段

    例2:  求每个部门的平均工资

    ret=Emp.objects.values("dep").annotate(avg_salary=Avg("salary"))

    # 按部门分组  求平均工资

    例3:  求每个出版社  出版的书的个数

    ret=Book.objects.values("pubish__id").annotate(c=Count(1))

    #publish__id是Book表里的字段

    print(ret)

    #[{"publish_id":1, "c":2},  {"publish_id":2, "c":1},  {"publish_id":3, "c":1}]

    跨表分组查询       以哪个字段分组 就把哪个字段放在values()里

    例1:  查询每个出版社名称以及出版过的书的平均价格   查询什么 就以什么为基表简单点

    ret=Publish.objects.values("nid").annotate(avg_price=Avg("book__price"))

    # book__price拼表       按Publish表的nid分组

    例2:  查询每一个作者的名字以及出版过的书的最高价    查询什么 就以什么为基表简单点

    ret=Author.objects.values("name").annotate(maxPrice=Max("book__price"))

    # book__price去Book表找price

    例3: 查询每一个书名称以及对应的作者的个数   (Book  Author表)

    ret=Book.objects.values("title").annotate(Count("authors"))     ?????????

    例4:

    ret=Publish.objects.all().annotate(avg_price=Avg("book_price")).values("name","email","avg_price")

    #前面的查询结果  后面可以用????????????

    例5:  查询作者数不止一个的书名以及作者的个数  (重点看看)

    ret=Book.objects.annotate(c=Count("authors").filter(c__gt=1).values("title","c"))

    # 添加到了Book对象的属性中了

    -------------------------------------------------------------------------

    F和Q查询:

    F函数查询

    例1:  查询评论数大于100的书名       以哪个字段分组 就把哪个字段放在values()里

    ret=Book.objects.filter(comment_count__gt=100).values("title")

    例2:  评论数大于点赞数

    from django.db.models. import F,Q  (导入F Q函数)

    ret=Book.objects.filter(comment_count__gt=F("poll_count"))

    例3:  评论数大于2倍点赞数

    ret=Book.objects.filter(comment_count__gt=F("poll_count")*2)

    例4:  每本书的价格都在原价上加100

    ret=Book.objects.all().update(price=100 + F("price"))

    Q函数

    例1:   查询价格大于300或者评论数大于3000的书籍

    ret=Book.objects.filter(Q(price__gt=300 | Q(comment_count__gt=3000)))

  • 相关阅读:
    android的一些类库的优缺点
    中文后乱码问题的解决方法(可能解决)
    android data recovery and nc
    最短路径——Floyd,Dijkstra(王道)
    还是畅通工程——最小生成树(王道)
    More is better——并查集求最大集合(王道)
    畅通工程——并查集(王道)
    IDEA默认VIM模式
    命令行杀死进程
    进制转换——高精度整数(王道)
  • 原文地址:https://www.cnblogs.com/kenD/p/9867925.html
Copyright © 2020-2023  润新知