Django ORM跨表查询&聚合、分组查询

1、正向查询和反向查询的概念

# 正向查询按字段,反向查询按表名小写


# 一对一
    # 正向:author---关联字段在author表里--->authordetail        按字段
    # 反向:authordetail---关联字段在author表里--->author        按表名小写
        # 查询jason作者的手机号   正向查询
        # 查询地址是 :山东 的作者名字   反向查询
      
# 一对多
    # 正向:book---关联字段在book表里--->publish        按字段
    # 反向:publish---关联字段在book表里--->book        按表名小写_set.all() 因为一个出版社对应着多个图书

# 多对多
    # 正向:book---关联字段在book表里--->author        按字段
    # 反向:author---关联字段在book表里--->book        按表名小写_set.all() 因为一个作者对应着多个图书


2、基于对象的表查询

# 正向
# 查询书籍是三国演义的出版社邮箱
book_obj = models.Book.objects.filter(title='三国演义').first()
print(book_obj.publish.email)
# 查询书籍是三国演义的作者的姓名
book_obj = models.Book.objects.filter(title='三国演义').first()
print(book_obj.authors)  # app01.Author.None
print(book_obj.authors.all())
# 查询作者为jason电话号码
user_obj = models.Author.objects.filter(name='jason').first()
print(user_obj.authordetail.phone)

# 反向
# 查询出版社是东方出版社出版的书籍                  一对多字段的反向查询
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set)  # app01.Book.None
print(publish_obj.book_set.all())

# 查询作者jason写过的所有的书                      多对多字段的反向查询
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set)  # app01.Book.None
print(author_obj.book_set.all())

# 查询作者电话号码是110的作者姓名                   一对一字段的反向查询
authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(authordetail_obj.author.name)


3、基于双下滑线的查询

# 正向
# 查询书籍为三国演义的出版社地址;publish__addr中的publish是那张表,addr就是表的字段
res = models.Book.objects.filter(title='三国演义').values('publish__addr','title')
print(res)
# 查询书籍为三国演义的作者的姓名
res = models.Book.objects.filter(title='三国演义').values("authors__name",'title')
print(res)
# 查询作者为jason的家乡
res = models.Author.objects.filter(name='jason').values('authordetail__addr')
print(res)

# 反向
# 查询南方出版社出版的书名
res = models.Publish.objects.filter(name='南方出版社').values('book__title')
print(res)
# 查询电话号码为120的作者姓名
res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
print(res)
# 查询作者为jason的写的书的名字
res = models.Author.objects.filter(name='jason').values('book__title')
print(res)
# 查询书籍为三国演义的作者的电话号码
res = models.Book.objects.filter(title='三国演义').values('authors__authordetail__phone')
print(res)


4、正向、反向混合案例

# 查询jason作者的手机号
# 正向
res = models.Author.objects.filter(name='jason').values('authordetail__phone')
print(res)
# 反向(表名小写)
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
print(res)

# 查询出版社为东方出版社的所有图书的名字和价格
# 反向
res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price')
print(res)
# 正向
res = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
print(res)

# 查询东方出版社出版的价格大于400的书
# 正向
res = models.Publish.objects.filter(name="东方出版社",book__price__gt=400).values('book__title','book__price')
print(res)
# 反向
res = models.Book.objects.filter(price__gt=400,publish__name='东方出版社').values('title','price')
print(res)


5、聚合、分组查询

配置文件配置参数查看所有orm操作内部的sql语句:

#将以下内容写入settings.py中即可,在输出结果时,会显示出相对应的SQL语句
LOGGING = {
            'version': 1,
            'disable_existing_loggers': False,
            'handlers': {
                'console':{
                    'level':'DEBUG',
                    'class':'logging.StreamHandler',
                },
            },
            'loggers': {
                'django.db.backends': {
                    'handlers': ['console'],
                    'propagate': True,
                    'level':'DEBUG',
                },
            }
        }


#需要在测试文件中先导包
from django.db.models import Max,Min,Count,Sum,Avg

# 聚合查询  aggregate
# 查询所有书籍的作者个数,count_num是别名
res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('authors'))
print(res)
# 查询所有出版社出版的书的平均价格
res = models.Publish.objects.aggregate(avg_price=Avg('book__price'))
print(res)  # 4498.636
# 统计东方出版社出版的书籍的个数
res = models.Publish.objects.filter(name='东方出版社').aggregate(count_num=Count('book__id'))
print(res)


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

猜你喜欢

转载自www.cnblogs.com/weiyiming007/p/12366956.html