Django 之多表查询 与多表的使用
Posted gukai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 之多表查询 与多表的使用相关的知识,希望对你有一定的参考价值。
1.django的多表查询 主要区分为: 正向查询 逆向查询
1. 多表查询: 是一个复杂的查询,他分为对象查询和__模糊查询两种方式 2. 多表查询: 又分为 一对一查询, 一对多查询, 多对多查询 三种方式 3. 多表查询: 分为正向查询 与 逆向查询, 正向查询 是根据 这个表中的外键属性名开始出发查询的跨表查询 逆向查询 是根据 根据关联表的 类名 小写 开始 进行跨表查询 4. 多表查询: 外键的存放位置如下: # 一对多:出版社(一) 书籍(多,外键在多的一方,依赖于出版社) # 一对一:作者详情(一) 作者(一,外键在任意一方均可,一旦外键放在作者中,作者依赖于作者详情) # 多对多:作者(多)书籍(多)建立关系表(存放两个表的外键信息 => 将建表转化为关系对应字段 5. 多表查询: 逆向查询遇到多条结果,在类名后再添加_set
2. 一对多关系 的增:
# 主键操作 # publish = Publish.objects.create(name=‘小女孩出版社‘, address=‘山东‘) # publish_id = publish.id # Book.objects.create(name=‘死亡Python‘, price=66.66, publish_date=‘2018-8-8‘, publish_id=publish_id) # 注意 publish_id = 其实就是publish表的id号进行匹配
# 对象操作 # publish = Publish.objects.first() # Book.objects.create(name=‘圣斗士‘, price=888.88, publish_date=‘1970-1-1‘, publish=publish)
3.一对多关系 的 删除:
book = Book.objects.last() # type: Book #拿到书中的最后一个对象 book.delete() #删除书对象 Publish.objects.first().delete() #删除出版社的第一个对象
4. 一对多关系的 改操作:
publish_id = Publish.objects.last().id #拿到对象的id号 Book.objects.filter(name=‘死亡Python‘).update(publish_id=publish_id)
5.一对一关系的 增加操作
# detail = AuthorDetail.objects.create(age=8, telephone=13766668888, info=‘一个字,帅‘) # Author.objects.create(name="Owen", author_detail=detail)
# detail = AuthorDetail.objects.create(age=8, telephone=13766668888, info=‘一个字,帅‘) # Author.objects.create(name="Liuxx", author_detail_id=detail.id) # 三句一起执行,两个作者使用一条详情,不满足唯一约束
6.一对一关系的 删除操作
AuthorDetail.objects.last().delete()
7. 多表的重难点 查询功能:
四:# 连表查询规则 # 1. 正向逆向概念:从存放外键的表到关系表称之为正向跨表查询,反之称之为逆向查询 # 2. 正向查询通过外键属性名进行跨表查询 # 3. 逆向查询通过关联表对应类名小写进行跨表查询 # 在连表查询规则规则之上,逆向查询遇到多条结果,在类名后再添加_set # 1、一对多表查询 # 需求:打印第一本书的出版社名 book = Book.objects.first() print(book.publish.name) # 注意这里book拿到的是对象 book 在通过外键属性名进行跨表出版社拿名字 # 需求:第一个出版社出版过的书们的名字, publish = Publish.objects.first() #拿到的第一个出版社的对象 print(publish.book_set.all()) # 因为出版社有好多书 所有要_set for book in publish.book_set.all(): # 在通过出版社 出版过的书们进行名字查询 print(book.name) # 需求:打印第二本书的出版社地址 address = Book.objects.all()[1].publish.address #运用了单表查询的切片功能 print(address) # 这里也是正向查询, 通过书对象的外键属性名, 在publish表中的地址 # 需求:第二个出版社出版过的书们的价格 publish = Publish.objects.all()[1] # type: Publish # 先拿到第二个出版社的对象 for book in publish.book_set.all(): # 第二个出版社出过的书们进行 精确查询 print(book.price) # 2、一对一关系的 表的查询 author = Author.objects.first() # type: Author print(author.author_detail.telephone) author_detail = AuthorDetail.objects.last() # type: AuthorDetail print(author_detail.author.name) # 3、多对多 表的关系查询 # 需求:第一本书的作者们的姓名 book = Book.objects.filter(name="圣斗士").first() # type: Book # print(book.author) for author in book.author.filter(name__endswith="xx"): print(author.name) # 需求:第二个作者写过的书们的书名 author = Author.objects.all()[1] # type: Author for book in author.book_set.all(): print(book.name) # 需求:第一个出版社出版过的书们的名字与价格 publish = Publish.objects.first() books = publish.book_set.all() # 数据所有字段数据都被保留存放在对象(们)中 for book in books: print(book.name, book.price) # 5、多级跨表查询 # 需求:第一个出版社出版过书们的作者们的电话号码 publish = Publish.objects.first() # type: Publish #拿到的第一个出版社的对象 books = publish.book_set.all() # 这个出版社出版过的书们 for book in books: # type: Book authors = book.author.all() # type: Author # 这本书的作者们 for author in authors: # type: Author # 在通过作者进行信息查询 print(author.author_detail.telephone)
8. 多表查询难点, 基于双下划线的跨表查询功能实现:
五. 基于双下划线的跨表查询:注:不能出现对象 , # 1、一对多 # 需求:第一本书的出版社名 # publish_name = Book.objects.filter(id=1).values(‘publish__name‘) # print(publish_name) # 需求:第一个出版社出版过的书们, # books_infos = Publish.objects.filter(id=1).values(‘book__name‘, ‘book__price‘) # print(books_infos) # 2、一对一 # 需求: 查询所有大于80岁作者的名字与实际年龄 # authors_infos = Author.objects.filter(author_detail__age__gt=80).values(‘name‘, ‘author_detail__age‘) # print(authors_infos) # 多级连表查询 # 多表关联:查询出版社在上海的出版过的所有书的 作者姓名、作者电话、具体出版社名 的相关信息 # infos = Publish.objects.filter(address__contains=‘上海‘).values(‘book__author__name‘, ‘book__author__author_detail__telephone‘, ‘name‘) # print(infos)
作业: 查询语句的用法
作业讲解:: # 地址在北京的出版社出版的书名 # books = Book.objects.filter(publish__address__contains=‘北京‘) # for book in books: # print(book.name) # 价格超过50元的书籍的出版社名 # publishs = Publish.objects.filter(book__price__gt=50).distinct() # for p in publishs: # print(p.name) # 获取所有名字里包含字母o(不区分大小写)作者的电话号码 # ads = AuthorDetail.objects.filter(author__name__icontains=‘o‘) # for ad in ads: # print(ad.telephone) # 年龄是20岁作者的作者名 # aus = Author.objects.filter(author_detail__age=20) # for ad in aus: # print(ad.name) # 获取第三位作者出版过的书的书名 # bs = Author.objects.all()[2].book_set.all() # for b in bs: # print(b.name) # 获取最后一本书作者们的简介 # aus = Book.objects.last().author.all() # for au in aus: # type: Author # print(au.author_detail.info) # 获取第一个出版社出版的最近一次出版的书的作者们的详情 # f_p = Publish.objects.first() # print(f_p) # f_p_bs = f_p.book_set.all() # print(f_p_bs) # f_p_bs_last = f_p_bs.order_by(‘publish_date‘).last() # print(f_p_bs_last) # aus = f_p_bs_last.author.all() # print(aus) # # aus = Publish.objects.first().book_set.all().order_by(‘publish_date‘).last().author.all() # for au in aus: # type: Author # print(au.author_detail.info) # 获取地址在上海的出版社名,与出版过的书名 # res = Publish.objects.filter(address__contains=‘上海‘).values(‘book__name‘, ‘name‘) # print(res) # 获取2018年出版的书名、书的价格与出版社名 # res = Book.objects.filter(publish_date__year=2018).values(‘name‘, ‘price‘, ‘publish__name‘) # print(res) # 获取年龄小于20岁作者的名字、年龄、电话与简介 # res = AuthorDetail.objects.filter(age__lt=20).values(‘author__name‘, ‘age‘, ‘telephone‘, ‘info‘) # print(res) # 获取名字中包含e(不区分大小写)的作者出版过的书的书名与价格(需要去重) # res = Author.objects.filter(name__icontains=‘e‘).values(‘book__name‘, ‘book__price‘).distinct() # print(res) # 获取书籍价格不超过50元的作者名与作者电话(需要去重) # res = Book.objects.filter(price__lte=50).values(‘author__name‘, ‘author__author_detail__telephone‘).distinct() # print(res) # 获取在老男孩出版过书的年龄最大的作者的作者名、年龄、电话与简介 res = Author.objects.filter(book__publish__name__contains=‘老男孩‘).values(‘name‘, ‘author_detail__age‘).order_by(‘author_detail__age‘).last() print(res)
以上是关于Django 之多表查询 与多表的使用的主要内容,如果未能解决你的问题,请参考以下文章