django-多表操作2

Posted zhuchunyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django-多表操作2相关的知识,希望对你有一定的参考价值。

#######多表操作二########

昨天写了基于双下划线查找,都是两个表之间查找,那再多跨几个表呢?还是一样,一步一步分析

# 跨多表查询:
    查询红楼梦这本书的作者的电话:
    (Author,Book,Authorinfo三张表对吧)
    Book作为基表:
        ret = models.Book.objects.filter(name=红楼梦).values(author__authorinfo__phone)
    Author作为基表
        ret = models.Author.objects.filter(book__name=红楼梦).values(authorinfo__phone)
    Authorinfo作为基表:
        ret = models.Authorinfo.objects.filter(author__book__name=红楼梦).values(phone)

    # 上面三种方式查询出来的结果的都是一样,方法也是一样,我拿第一句为例来说。
    # 首先看要求已知什么,就红楼梦这本书对吧,那我们的筛选条件的书名为红楼梦对吧,
    # 以谁为基表都可以,我以Book作为基表,Book下面是不是就有书名(name),所以我们可以之间通过name=‘红楼梦‘可以找到那本书
    # 继续看要求,要我们查询的作者的电话,这个作者电话再Authorinfo表中,而这个只和Author表有关系,
    # 那我们怎么通过Book表去找到Author表,Book表下面是不是有author字段(多对多的关系),所以正向查找按字段,找到Author表,
    # Author表下面也有authorinfo字段,继续正向查找,就能找到phone字段,所以author__authorinfo__phone,就能找到。

    # 自己琢磨以Author、Authorinfo做基表查找

    查询重庆出版社出版的的书籍它所有作者的手机号:
    (Author,Book,Authorinfo,Publish四张表对吧)
    Author作为基表:
        ret = models.Author.objects.filter(book__publish__name=重庆出版社).values(authorinfo__phone)
    Book作为基表:
        ret = models.Book.objects.filter(publish__name=重庆出版社).values(author__authorinfo__phone)
    Authorinfo作为基表:
        ret = models.Authorinfo.objects.filter(author__book__publish__name=重庆出版社).values(name)
    Publish作为基表:
        ret = models.Publish.objects.filter(name=重庆出版社).values(book__author__authorinfo__phone)

    查询重庆出版社出版的的书籍它所有作者的名字和手机号码:
        不写了,看到这文章的人,自己写写吧,我上面的代码values只传了一个参数,他可以传多个(提醒你了)
        上一篇多表操作有我建立的models,关系都在上面,没有改动

继续写聚合查询,这个和mysql里面的聚合函数一样。
    首先是要导入的方法的
    from django.db.models import Svg,Max,Min,Sum

    # 查询重庆出版社出版的书籍中,价钱最高,价钱最低,平均价钱,总价钱
        ret = models.Publish.objects.filter(name=北京出版社).aggregate(Max(book__price),Min(book__price),Avg(book__price),Sum(book__price))

    # 查询所有书籍价钱最大的
        ret = models.Book.objects.all().aggregate(max=Max(price))
        ret1 = models.Book.objects.all().aggregate(Max(price))
        print(ret)
        print(ret1)
    下面是依次的打印结果:
        {max: Decimal(99.99)}
        {price__max: Decimal(99.99)}

    # 我想说的是,我们可以指定返回值的key值,不指定的话会默认以参数__方法名命名
    # 调用aggregate这个方法之后,它的返回值就是一个字典了,不再是queryset对象,就不能再用它的方法了。


分组查询,也是就mysql中的group by
    from django.db.models import Svg,Max,Min,Sum,Count
    # 统计每一本书作者个数
    ret = models.Book.objects.all().annotate(count=Count(author))
    for i in ret:
        print(书名:{}--作者个数:{}.format(i.name,i.count))

    # 统计每一个出版社的最便宜的书
    ret = models.Publish.objects.all().annotate(min=Min(book__price)).values(Book__name,min)
    print(ret)

    # 统计每一本以西开头的书籍的作者个数:
    ret = models.Book.objects.all().filter(name__startswith=).annotate(count=Count(author)).values(name,count)
    print(ret)

    # 统计不止一个作者的图书:(作者数量大于一)
    ret = models.Book.objects.all().annotate(c=Count(author)).filter(c__gt=1).values(name,c)
    print(ret)

    # 首先调用annotate方法它的返回值是一个queryset对象

说说F查询:
    from django.db.models import F
    先让我去models文件中Book表中加几个字段,并在数据库中随便加点数据
    comments_num = models.IntegerField(default=0)
    # 这本书评论数
    read_num = models.IntegerField(default=0)
    # 这本书的阅读数

    # 查看所有书中,评论数大于阅读数的书名
    ret = models.Book.objects.all().filter(comments_num__gt=F(read_num)).values(name)
    print(ret)

    # 让所有的书,阅读数+55
    models.Book.objects.all().update(read_num=F(read_num)+55)

    # F的用法就是,比如评论数大于阅读数,comments_num__gt=read_num,这样写是不对的,等号右边必须是个值
    # 你放一个字段名是不对,我们可以通过F,将字段名给包裹起来,就写达到我们想要的效果。
    # F一般用在两个字段向比较的时候,等号右边那个字段。

最后就是Q查询。
    Q这是一个类,一般用于逻辑处理

 

以上是关于django-多表操作2的主要内容,如果未能解决你的问题,请参考以下文章

django模型层2 多表操作

django的多表操作

Django -- 多表操作

Django_多表查询

python django基础五 ORM多表操作

django学习-34.多对多表关系对应的完整业务操作