Django之ORM多表操作之跨表查询

一.基于对象的跨表的查询------类似于子查询

正向查询和反向查询:
比方说是出版社表和书籍表,有可能我知道这本书的名字,但是不知道出版社是哪一个,有可能知道这个出版社,但是我想知道这个出版社出版过那些书,这就是正向查询和反向查询,怎么区分正向和反向呢,这个要看我们外键字段定义在那张表(类)里面,上篇博文我们的book表中的publish外键到出版社这个表,我们从book表去查询publish表中的数据就是正向,从publish表去查询book表中的数据就是反向查询。

  1. 一对一
 # 正向查询
    # 查询张胜男的电话
    obj = models.Author.objects.filter(name='张胜男').first()
    print(obj.authorDetail)  #北京沙河
    print(obj.authorDetail.telephone)  #北京沙河
    #正向查询 obj.authorDetail 对象.属性

    #反向查询
    #查询2222电话号是谁的
    obj= models.AuthorDetail.objects.get(telephone='2222')
    print(obj.author.name)
    #反向查询 obj.author 对象.表名小写     
   
  1. 一对多
    # 查询金瓶梅这本书出版社是那个
    # 正向查询
    obj = models.Book.objects.get(title='金瓶梅')
    print(obj.publishs.name)    #光学出版社
    print(obj.publishs)         #光学出版社 这里也打印是因为我们表中有__str__这个方法
    # 正向查询:obj.publishs 对象.属性

    # 反向查询
    # 光学出版社出版过那些书
    obj= models.Publish.objects.get(name='光学出版社')
    print(obj.book_set.all())  #book_set:多对多的关系django认为会是多条  obj.book_set:类似于一个控制器在调用all方法取所有的数据
    # 反向查询:obj.book_set.all()  对象.表名小写_set
    这里需要注意一下:如果表中的外键字段中有参数related_name='xx'  这里做反向查询的时候直接使用obj.xx.all()不再是小写的表名 正向不会影响
  1. 多对多
# 金瓶梅这本书是谁写的
# 正向查询
obj = models.Book.objects.get(title='金瓶梅')
print(obj.authors.all())
#正向查询:obj.authors 对象.属性

#反向查询
# 张胜男写了那些书
obj = models.Author.objects.get(name='张胜男')
print(obj.book_set.all())
#反向查询:obj.book_set  对象.表名小写_set

二.基于双下划线的跨表查询------连表 join

一对一:

    # 查询张胜男的电话
    # 方式一:
    # 正向查询
    obj = models.Author.objects.filter(name='张胜男').values('authorDetail__telephone')
    print(obj) #<QuerySet [{'authorDetail__telephone': '2222'}]>

    # 方式二:
    # 反向:
    obj = models.AuthorDetail.objects.filter(author__name='张胜男').values('telephone','author__age')
    print(obj)  #<QuerySet [{'telephone': '2222'}]>

    # 查询那个老师的电话是2222
    # 正向:
    obj = models.Author.objects.filter(authorDetail__telephone='2222').values('name')
    print(obj)  #<QuerySet [{'name': '张胜男'}]>

    #反向
    obj = models.AuthorDetail.objects.filter(telephone='2222').values('author__name')
    print(obj)  #<QuerySet [{'name': '张胜男'}]>

一对多:

# 查询金瓶梅这本书出版社是那个
# 正向:
obj = models.Book.objects.filter(title='金瓶梅').values('publishs__name')
print(obj) #<QuerySet [{'publishs__name': '光学出版社'}]>

# 反向查询:
obj= models.Publish.objects.filter(book__title='金瓶梅').values('name')
print(obj) #<QuerySet [{'name': '光学出版社'}]>
这里需要注意一下:如果表中的外键字段中有参数related_name='xx'  这里做反向查询的时候直接使用xx__title不再是小写的表名 正向不会影响
# 光学出版社出版过那些书
# 正向查询:
obj = models.Publish.objects.filter(name='光学出版社').values('book__title')
print(obj)

# 反向查询:
obj = models.Book.objects.filter(publishs__name='光学出版社').values('title')
print(obj) #<QuerySet [{'title': '金瓶梅'}]>

多对多:

    # 金瓶梅这本书是谁写的
    # 正向:
    obj = models.Book.objects.filter(title='金瓶梅').values('authors__name')
    print(obj)

    # 反向查询:
    obj = models.Author.objects.filter(book__title='金瓶梅').values('name')
    print(obj)

    # 张胜男写了那些书
    # 反向:
    obj = models.Author.objects.filter(name='张胜男').values('book__title')
    print(obj)

    #正向:
    obj = models.Book.objects.filter(authors__name='张胜男').values('title')
    print(obj)

三.基于双下划线的进阶查询

 	# 光学出版社 出版的书的名称以及作者的名字
    obj = models.Book.objects.filter(publishs__name='光学出版社').values('authors__name','title')
    print(obj)
    obj = models.Publish.objects.filter(name='光学出版社').values('book__title','book__authors__name')
    print(obj)
    obj = models.Author.objects.filter(book__publishs__name='光学出版社').values('book__title','name')
    print(obj)

    # 手机号以1开头的作者出版过的所有书籍名称以及出版社名称
     obj = models.AuthorDetail.objects.filter(telephone__startswith='1').values(
         'author__book__title','author__book__publishs__name')
    print(obj)

    obj= models.Author.objects.filter(authorDetail__telephone__startswith='1').values(
         'book__title','book__publishs__name')
    print(obj)

    obj = models.Publish.objects.filter(book__authors__authorDetail__telephone__startswith='1').values(
        'book__title','name'
    )
    print(obj)

    obj = models.Book.objects.filter(authors__authorDetail__telephone__startswith='1').values(
         'title','publishs__name'
     )
    print(obj)

四.聚合查询

from django.db.models import Avg,Max,Min,Sum,Count
obj = models.Book.objects.all().aggregate(a=Avg('price'))  #a:起别名  Avg:平均值
obj = models.Book.objects.all().aggregate(a=Max('price'))   #Max:最大值
obj = models.Book.objects.all().aggregate(a=Min('price'))   #Min: 最小值
obj = models.Book.objects.all().aggregate(a=Sum('price'))   #Sum: 价格加在一起
obj = models.Book.objects.all().aggregate(a=Count('price')) #Sum: 总数据
print(obj)  #{'a': } 返回一个字典 结束orm语句

猜你喜欢

转载自blog.csdn.net/qq_39253370/article/details/105184885