首页 > 其他 > 详细

16.Django(基于双下划线的进阶查询、related_name、聚合查询、分组查询)

时间:2020-06-08 20:10:06      阅读:52      评论:0      收藏:0      [点我收藏+]

双下划线的进阶查询

  • 三张表的进阶查询

    需求:查询指定出版社的书籍名称和作者名字

    Publish、Book、Author涉及三张表,我们就有三种方式。涉及多少张表,我们就有多少种方式去做。

    • 正向查询

      obj = models.Book.objects.filter(Publish__name=‘xx出版社‘).values(
      ‘title‘,
      ‘Author__name‘,
      )
    • 反向查询

      # 方式1:
      obj = models.Publish.object.filter(name=‘xx出版社‘).values(
      ‘book__title‘,
         ‘book__author__name‘,
      )
      ?
      ?
      # 方式2:
      obj = models.Author.objects.filter(book__Publish__name=‘IT出社‘).values(
         ‘book__title‘,
         ‘name‘,
      )
      print(obj)
  • 四张表的进阶查询

    需求:手机号为166开头的作者出版的所有书籍名称以及出版社名称

    AuthorDetail、Author、Book、Publish

    • 正向查询

      # 方式1:
      obj = models.Author.objects.filter(AuthorDetail__telephone__startswith=‘166‘).values(
      ‘book__title‘,
         ‘book__Publish__name‘
      )
      ?
      ?
      ?
      # 方式2:
      obj = models.Book.objects.filter(Author__AuthorDetail__telephone__startswith=‘166‘).values(
         ‘title‘,
         ‘Publish__name‘,
      )
      print(obj)
    • 反向查询

      # 方式1:
      obj = models.AuthorDetail.objects.filter(telephone__startswith=‘166‘).values(
      ‘author__book__title‘,
         ‘author__book__Publish__name‘,
      )
      print(obj)
      ?
      ?
      # 方式2:
      obj = models.Publish.objects.filter(book__Author__AuthorDetail__telephone__startswith=‘166‘).values(
         ‘book__title‘,
         ‘name‘,
      )
      print(obj)

 

related_name (了解)

面试曾经考过:related_name是什么?用在哪里?

基于对象的查询如果我们进行反向查询需要获取关联表的表名;基于双下划线的连表查询我们在连表的时候,也需要获取表的名字__。

‘‘‘
测试:
我们给book表中的publish字段加一个此属性
‘‘‘
Publish = models.ForeignKey(to=‘Publish‘, on_delete=models.CASCADE, related_name=‘xx‘)
?
# 重新makemirations、migrate
?
?
?
?
# 测试基于对象的查询
?
# 正向查询:需求:查询指定书的出版社
obj = models.Book.objects.get(title=‘指定的书名‘)
print(obj.publish.name)  # related_name 不影响
?
# 反向查询:需求:查询指定出版社出版的书名
obj = models.Publish.objects.get(name=‘指定出版社‘)
# print(obj.book_set.all()) # 查不到
print(obk.xx.all())
?
related_name 这个属性替代了反向查询时需要 类名_set 这个方法
?
?
?
?
# 基于双下划线连表的操作
?
# 正向查询:需求:查询指定书的出版社
obj = models.Book.objects.filter(title=‘指定书‘).values(
‘publish_name‘,
)
print(obj)
?
# 反向查询:需求:查询指定书的出版社
# obj = models.Publish.objects.filter(book__title=‘指定书名‘).values(
# ‘publihs__name‘,
# )
# print(obj)   # 报错
?
obj = models.Publish.objects.filter(xx__title=‘指定书名‘).values(
   ‘publish__name‘,
)
print(obj)

小结:

  • related_name只是适用于反向查询

  • 基于对象那个的反向查询时需要类名_set这种方法替换成了你设置的related_name就行了;基于双下划线的反向查询将类名__字段替换成related_name__字段

 

 

 

聚合查询:

mysql中有什么聚合函数?

统计:count()
最大:max()
最小:min()
求和:sum()
平均值:avg()
?
聚合字段:concat()

orm也是支持这些聚合函数的

需要先引入

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

使用聚合查询需要使用aggregate(),在括号里面写聚合函数

# 注意:聚合函数导入和使用时,开头字母要大写
?
from django.db.models import Max,Min,Avg,Sum,Count
num = models.Book.objects.aggregate(Sum(‘price‘))
print(num)

aggregate()这个方法返回的是一个字段,返回一个字段就意味着这句话终结了。结束了。

 

 

分组查询:

将同类的分成一组统计或者计算一些内容,一般都是找重复性较高的字段进行分组。在orm中有两种方式(一般多用于第二种)

  • 方式1:

    需求:查询每个出版社的书籍的平均价格

    # 原生mysql语句
    select avg(price) from app01_book group by publish_id;
    # orm 语句
    res = models.Book.objects.values(‘Publish_id‘).annotate(a=Avg(‘price‘))
    # 这里的values加分组的字段也就是原生mysql语句中的group by。
    # annotate里面放置的就是分组之后要统计的内容。
    print(res)

    方式1的优点:可以进行多条件的分组

    res = models.Book.objects.values(‘publish_id‘,‘id‘).annotate(a=Avg(‘price‘))    print(res)
  • 方式2:

    需求:拆线呢每个出版社出版的书籍的平均价格

    原理是基于双下划线连表操作的

    res = models.Publish.objects.annotate(a=Avg(‘book__price‘))
    print(res)
       
    res = models.Publish.objects.annotate(a=Avg(‘book__price‘)).values(‘name‘,‘a‘)
    print(res)

    优点:在此种写法基础上,可以进行进一步的筛选

    需求:查询每个出版社出版的书籍的平均价格大于100的

    res = models.Publish.objects.annotate(a=Avg(‘book_price‘)).valeus(‘name‘,‘a‘).filter(a__gt=100)
    # filter 充当的是having的作用
    print(res)

16.Django(基于双下划线的进阶查询、related_name、聚合查询、分组查询)

原文:https://www.cnblogs.com/muyangxiaodong/p/13067773.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!