Django之ORM查询进阶

Posted 黎明NB

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之ORM查询进阶相关的知识,希望对你有一定的参考价值。

基于双下划线的双表查询

分组与聚合函数

基于双下划线的双表查询

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

技术分享
# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)

    # 正向查询 按字段:publish

    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","price")

    # 反向查询 按表名:book

    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__price")



# 练习2: 查询egon出过的所有书籍的名字(多对多)

    # 正向查询 按字段:authors:
    queryResult=Book.objects
            .filter(authors__name="yuan")
            .values_list("title")

    # 反向查询 按表名:book
    queryResult=Author.objects
              .filter(name="yuan")
              .values_list("book__title","book__price")


# 练习3: 查询人民出版社出版过的所有书籍的名字以及作者的姓名


    # 正向查询
    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","authors__name")
    # 反向查询
    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__authors__age","book__authors__name")


# 练习4: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称

    queryResult=Book.objects
            .filter(authors__authorDetail__telephone__regex="151")
            .values_list("title","publish__name")
代码

 注意:

反向查询时,如果定义了related_name ,则用related_name替换表名,例如: publish = ForeignKey(Blog, related_name=‘bookList‘):

技术分享
# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)
 
    # 反向查询 不再按表名:book,而是related_name:bookList
 
    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("bookList__title","bookList__price")
代码

注意:    双下划线的跨表查询  不用__set了

聚合查询与分组查询

聚合:aggregate(*args, **kwargs)

技术分享
:aggregate(*args, **kwargs)
1
2
3
4
# 计算所有图书的平均价格
    >>> from django.db.models import Avg
    >>> Book.objects.all().aggregate(Avg(price))
    {price__avg: 34.35}
View Code

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

技术分享
>>> Book.objects.aggregate(average_price=Avg(price))
{average_price: 34.35}
View Code

如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg(price), Max(price), Min(price))
{price__avg: 34.35, price__max: Decimal(81.20), price__min: Decimal(12.99)}#Decimal数据格式

分组:annotate()

QuerySet中每一个对象都生成一个独立的汇总值。

(1) 练习:统计每一本书的作者个数

技术分享
  #查询每一本书的作者个数
    # ret= models.Book.objects.all().annotate(c=Count("authorlist__name"))
    # print(ret)#Queryset对象
View Code

(2)每一个出版社出版过的最便宜的书:
技术分享
cc=models.Publish.objects.all().annotate(s=Min("book__price"))#如果是跨表查询就用表明__加id
    for i in cc:
        print(i.s)
View Code

annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:

queryResult= Publish.objects
            .annotate(MinPrice=Min("book__price"))
            .values_list("name","MinPrice")
print(queryResult)

方式2:

queryResult=Book.objects.values("publish__name").annotate(MinPrice=Min(price))

注意:values内的字段即group by的字段

(3) 统计每一本以py开头的书籍的作者个数:

 queryResult=Book.objects
           .filter(title__startswith="Py")
           .annotate(num_authors=Count(authors))

(4) 统计不止一个作者的图书:

queryResult=Book.objects
          .annotate(num_authors=Count(authors))
          .filter(num_authors__gt=1)

(5) 根据一本图书作者数量的多少对查询集 QuerySet进行排序:

Book.objects.annotate(num_authors=Count(authors)).order_by(num_authors)

(6) 查询各个作者出的书的总价格:

# 按author表的所有字段 group by
    queryResult=Author.objects
              .annotate(SumPrice=Sum("book__price"))#跳转到另一个表里
              .values_list("name","SumPrice")
    print(queryResult)
    
#按authors__name group by
    queryResult2=Book.objects.values("authors__name")
              .annotate(SumPrice=Sum("price"))
              .values_list("authors__name","SumPrice")
    print(queryResult2)

注意:很多代码没有加models

 
 

 



以上是关于Django之ORM查询进阶的主要内容,如果未能解决你的问题,请参考以下文章

python3开发进阶-Django框架中的ORM的常用操作的补充(F查询和Q查询,事务)

python—day60 Object Relational Mapping(ORM) ORM连表查询 ORM进阶

Django框架——Q查询进阶ORM查询优化事务操作字段类型字段参数AjaxContent—Typeajax携带文件

Django基础之模型(models)层

django的数据库ORM进阶操作

Django进阶-ORM框架的一般操作