06-模型层3—多表操作之基于对象的跨表查询

06-模型层3—多表操作之基于对象的跨表查询

概述

1、几个需要注意的问题

(1)ORM最核心用的最多的就是跨表查询(多表查询)。
(2)所有的操作按照前面创建好的关联表与数据的基础上进行。 
(3)values()等同于select。
(4)filter()等同于where。   

2、跨表查询的分类

(1)基于对象查询
(2)基于双下划线查询
(3)聚合与分组查询
(4)F与Q查询

3、基于对象的跨表查询

基于对象的跨表查询————最终翻译成SQL语句都是“子查询”。
数据库中的一个表记录其实就是筛选出来的“对象”的一个对象————可以利用 .操作符操作。

4、查询规则

一对多与多对多:正向查询按字段;反向查询按表名小写_set.all()
一对一:正向查询按字段;反向查询按表名小写

一对多查询(Book与Publish)

1、

以Book表为基准,由于我们将关联的字段定义在了Book表中,也就是说“关联字段”在Book表中,所以从Book开始查是“正向”,从Publish开始查是“反向”。
Book类中是这样写的:

publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True)

2、

Book         book_obj.publish         >>   Publish
          ———————————————————————————————————— 
            <<<  publish_obj.book_set.all()#QuerySet author_boj1,author_obj2,......]

3、正向查询按字段—publish

#查询主键为1的书籍的出版社的城市
book_obj = Book.objects.filter(pk=1).first()
#正向查询按字段
##注意这里的book_obj.publish————是主键为1的书籍对象关联的出版社对象
ret = book_obj.publish.city
print(ret)

#同样的:“西游记”书籍的出版社的名字:
book_o = Book.objects.filter(title='水浒传').first()
ret = book_o.publish.name
print(ret)

4、反向查询按表名小写_set.all()—book_set.all()

#查询“苹果出版社”出版过的所有书籍的书名
publish_obj = Publish.objects.filter(name='苹果出版社').first()
#反向查询按表名小写_set
##注意 publish.book_set.all() ————是苹果出版社关联的所有“书籍对象”的集合
book_list = publish.book_set.all()
for book_obj in book_list:
    print(book_obj.title)

多对多查询(Book与Author,外加book_authors表)

1、

以Book表为基准,由于我们将关联的字段定义在了Book表中,也就是说“关联字段”在Book表中,所以从Book开始查是“正向”,从Author开始查是“反向”。
Book类中是这样写的:

authors = models.ManyToManyField(to='Author')

2、

Book        book_obj.authors.all()  >>  Author #QuerySet[author_boj1,author_obj2,...]
         ———————————————————————————————————— 
         <<<  author_obj.book_set.all()  

3、正向查询按字段—authors

#“三国群英”所有的作者及手机号
##先“过滤”
book_obj = Book.objects.filter(title='三国群英').first()
##正向查询按字段
##注意这里得到的 authors 是与这本书关联的所有 作者对象的集合
authors = book_obj.authors.all()
for author_obj in authors:
    name = author_obj.name
    ##手机号在“作者详细表”中,而且“作者表”相对于“作者详细表”是正向,关联字段为authordetail
    telephone = author_obj.authordetail.telephone
    print('作者:%s,手机号:%s'%(name,telephone))

4、反向查询按表名_set.all()—book_set.all()

#查询作者whw出版过的所有书籍的名字
##先“过滤”
author_obj = Author.objects.filter(name='whw').first()
##反向查询按表名小写_set
##注意这里得到的是该作者写过的书的对象的集合
book_list = author_obj.book_set.all()
for book_obj in book_list:
    print(book_obj.title)

一对一查询(Author与AuthorDetail)

1、

以Author表为基准,由于我们将关联的字段定义在了Author表中,也就是说“关联字段”在Author表中,所以从Author开始查是“正向”,从AuthorDetail开始查是“反向”。
Author类中是这样写的:

authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE)

2、

Author        author_obj.authordetail  >>      AuthorDetail 
             ———————————————————————————————————— 
             <<<    author_detail_obj.author_set

3、正向查询按字段

#查询作者whw的电话
author = Author.objects.filter(name='whw').first()
##正向查询按字段
ret = author.authordetail.telephone
print(ret)

4、反向查询按表名小写

#查询电话是12312312的作者名字
(1)##注意这里的 authordetail_list 是一个QuerySet对象,后面没有用first
authordetail_list = AuthorDetail.objects.filter(telephone=12312312)
for obj in authordetail_list:
    #反向查询用表名小写
    print(obj.author.name)

(2)也可以在后面加first() 
add = AuthorDetail.objects.filter(telephone=12312312).first()
#反向查询按表名小写:
print(add.author.name)
posted on 2019-05-19 10:11  江湖乄夜雨  阅读(127)  评论(0编辑  收藏  举报