Django ORM 之基于对象、双下划线查询

返回ORM目录 Django ORM

内容目录:

  一、 基于对象的表查询
  二、 基于双下划线的查询
  三、 聚合查询 aggregate
  四、 分组查询 annotate

一、 基于对象的表查询

1.正向查询  --> 意思是从含有外键表查询其外键对应的表的字段值 --> 正向查询容易推导
    (1)查询书籍是三国演义的出版社邮箱
        book_obj = models.Book.objects.filter(title='三国演义').first()
        结果:123.qq.com
        
    (2)查询书籍是 活着 的作者的姓名
        book_obj = models.Book.objects.filter(title='活着').first()
        # print(book_obj.authors)  # app01.Author.None 表示查询的数据有多个,需加上all()
        print(book_obj.authors.all())
        结果:<QuerySet [<Author: 作者对象的名字:jason>]>3)查询作者为jason电话号码
        user_obj = models.Author.objects.filter(name='jason').first()
        print(user_obj.authordetail.phone)
        结果:1110
 2.反向查询 --> 从外键不在本表开始查询对应关系表的数据 --> 相对要麻烦一点
 
    (1)查询出版社是南方出版社出版的书籍                  一对多字段的反向查询
        # 首先要确定的是,书籍与南方出版社是有关系的,但是外键在书籍那边,
        # 从出版社开始查询数据,先得到出版社对象,在使用固定语法跨表到book表中,最后拿到数据。
        publish_obj = models.Publish.objects.filter(name='南方出版社').first()
        print(publish_obj.book_set)  # app01.Book.None
        print(publish_obj.book_set.all())
​
  (2)查询作者jason写过的所有的书                      多对多字段的反向查询
        author_obj = models.Author.objects.filter(name='jason').first()
        print(author_obj.book_set)  # app01.Book.None
        print(author_obj.book_set.all())
​
   (3)查询作者电话号码是110的作者姓名                   一对一字段的反向查询
        authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first()
        print(authordetail_obj.author.name)

二、 基于双下划线的查询

 1.正向查询
    (1) 查询书籍为三国演义的出版社地址
    res = models.Book.objects.filter(title='三国演义').values('publish__addr','title')
     
    (2) 查询书籍为活着的作者的姓名
    res = models.Book.objects.filter(title='活着').values("authors__name",'title')
    
    (3)查询作者为jason的家乡
    res = models.Author.objects.filter(name='jason').values('authordetail__addr')
 2.反向查询
    (1)查询南方出版社出版的书名
    res = models.Publish.objects.filter(name='南方出版社').values('book__title')
    
    (2)查询电话号码为120的作者姓名
    res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
    
    (3)查询作者为jason的写的书的名字
    res = models.Author.objects.filter(name='jason').values('book__title')
    
    (4)查询书籍为三国演义的作者的电话号码
    res = models.Book.objects.filter(title='三国演义').values('authors__authordetail__phone')
(1)查询jason作者的手机号
 # 正向查询
    res = models.Author.objects.filter(name='jason').values('authordetail__phone')
    
 # 反向查询
    res = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
​
(2)查询出版社为东方出版社的所有图书的名字和价格
 # 正向查询
    res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price')
​
 # 反向查询
    res = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
​
(3)查询东方出版社出版的价格大于400的书
 # 正向查询
    res = models.Publish.objects.filter(name="东方出版社",book__price__gt=400).values('book__title','book__price')
 
 # 反向查询
    res = models.Book.objects.filter(price__gt=400,publish__name='东方出版社').values('title','price')

三、聚合查询 aggregate

1.需要先导包
from django.db.models import Max,Min,Count,Sum,Avg
​
2.例子
(1)查询所有书籍的作者个数
    res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('authors'))
​
(2)查询所有出版社出版的书的平均价格
    res = models.Publish.objects.aggregate(avg_price=Avg('book__price'))
​
(3)统计东方出版社出版的书籍的个数
    res = models.Publish.objects.filter(name='东方出版社').aggregate(count_num=Count('book__id'))
​

四、分组查询 annotate

1.例子
(1)统计每个出版社出版的书的平均价格
    res = models.Publish.objects.annotate(
        avg_price=Avg('book__price')).values('name','avg_price')
​
(2)统计每一本书的作者个数
    res = models.Book.objects.annotate(
        count_num=Count('authors')).values('title','count_num')
    
(3)统计出每个出版社卖的最便宜的书的价格
    res = models.Publish.objects.annotate(
        min_price=Min('book__price')).values('name','min_price')
    
(4)查询每个作者出的书的总价格
    res = models.Author.objects.annotate(
        sum_price=Sum('book__price')).values('name','sum_price')

 

 
posted @ 2019-06-13 15:18  xt12321  阅读(472)  评论(0编辑  收藏  举报