Django ORM多表查询

基于双下划线查询

根据存的时候,字段的数据格式衍生的查询方法

1、年龄大于35岁

res = models.AuthorDetails.objects.filter(age__lt=80)
print(res)

# 输出结果 <QuerySet [<AuthorDetails: yuhua@dd>, <AuthorDetails: cao@di.com>, <AuthorDetails: gao@doi.com>]>

2、年龄小于35岁

res = models.AuthorDetails.objects.filter(age__gt=80)
print(res)

# 输出结果 <QuerySet [<AuthorDetails: jinyong@qr.com>]>

 # 大于等于 小于等于
    # res = models.User.objects.filter(age__gte=32)
    # print(res)
    # res = models.User.objects.filter(age__lte=32)
    # print(res)

3、年龄等于48或者32

res = models.AuthorDetails.objects.filter(age__in=[48, 32])  # 表示or关系 列表括起来
print(res)

# 输出结果  <QuerySet [<AuthorDetails: cao@di.com>, <AuthorDetails: gao@doi.com>]>

4、年龄在48或者56岁之间的

res = models.AuthorDetails.objects.filter(age__range=[32, 56])  # 这里的range是包括头和尾的
print(res)

<QuerySet [<AuthorDetails: yuhua@dd>, <AuthorDetails: cao@di.com>, <AuthorDetails: gao@doi.com>]>

5、查询名字里面含有g的数据 模糊查询

# where name like '%i%'
res = models.Author.objects.filter(name__contains='i')
    # 对应SQL语句 'contains': 'LIKE BINARY %i%' 其中的BINARY是精确大小写 


res = models.Author.objects.filter(name__icontains='I')
# 'icontains': 'LIKE %s' 而’icontains’中的’i’表示忽略大小写

6、以查询名字以g结尾的

res = models.Author.objects.filter(name__endswith='g')
# 以g结尾的

res = models.Author.objects.filter(name__startswith='y')
# 以y开头的

7、导出9月份数据(重要)

res = models.User.objects.filter(create_time__month='04')
print(res)

# 这里需要注意的是时间字段不能设为DateTimeFiled否则是查不出来的

# 查询一年中某个月的数据
res = models.User.object.filter(create_time_month='04', create_time_year='2021')

一对多的增删改查

# 这里增加还是需要先建关联的那一张表
models.Book.objects.create(title='许三观卖血记', price=32.98, publish_id=2)

models.Book.objects.filter(pk=4).update(price=33.45)

# 删除的话会级联更新,级联删除。

book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish)

# 正向查询

多对多的增删改查

1.book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.add(3, 5)
# .author跳转到第三张表

2. author_obj = models.Author.objects.filter(pk=1).first()
	book_obj = models.Book.objects.filter(pk=1).first()
    book_obj.authors.add(author_obj)

book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.set([3, 5])

# 这里的set方法要放列表,可迭代对象

book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.remove(3,3)
# 书id=3对应着的作者id=3的删除

clear可以清空数据

book_obj = models.Book.object.filter(pk=3).first()
print(book_obj.author.all())

# 当查询结果为多个的时候,要加.all()
# 当查询结果为一个的时候,不要加.all()	
正反向的概念,为了更好的记忆
# 正向:比如外键字段在A表中,需要通过A表去查B表,那这个查询方向就是正向的
# 反向:比如外键字段在A表中,需要通过B表去查A表,那这个查询方向就是反向的

正向查询按字段查
反向查询按表名小写,或者表明小写_set.all()(有多个结果时)

聚合查询

使用聚合查询需要导入模块

from django.db.models import Max, Min, Sum, Count, Avg

聚合查询有一个关键字aggregate:

.aggregate(聚合函数名('字段名'))
 1 所有书的平均价格 select avg(price) from book where id > 2
     res = models.Book.objects.aggregate(Avg('price'))

    """
        聚合查询需要加aggregate
        分组查询需要加annotate
    """
     print(res)

res = models.Book.objects.aggregate(avg=Avg('price'), price_max=Max('price'), price_min=Min('price'), sum=Sum('price'), count=Count('price'))
     print(res)

分组查询

关键字annotate

# 1.统计每一本书的作者个数
res = models.Book.objects.annotate() # 默认就是按照models后面的表名分组
print(res)

res = models.Book.objects.annotate(count=Count('authors__pk')).values("title", 'count')
print(res)



# 2.统计每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(price_min=Min('book__price')).values('title', 'price_min')
# .values是为了更好的查看,返回一个可迭代的字典序列
print(res)

# <QuerySet [{'title': '雪山飞狐打折', 'price': Decimal('34.22'), 'publish': 3}]>




 # 3.统计不止一个作者的图书
# 1) 先查询每一本书的作者个数,
# 2) 在筛选出大于1的

res = models.Book.objects.annotate(author_num=Count('authors__pk')).filter(author_num__gt=1).values('title', 'author_num')
    print(res)

    """
    res = models.Book.objects.values('').annotate
    """
posted @ 2021-08-17 19:46  popopop  阅读(79)  评论(0)    收藏  举报