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')