django之模板层ORM操作

1.orm中常用命令

# models.Book.objects

# 增
create()

# 删
delete()

# 改
update()

# 查
filter()
exclude() # 与filter()取反,除条件之外的记录。
all()
get()----># 此命令可直接获取对象本身,但如果查找的记录不存在,则会报错。

# 获取queryset中的对象
first()
last()

# 其他
values() # 获取queryset中指定字段的数据,以字典形式
values_list() # 和values一样,以元组形式
count() # 计数 不接受任何参数
order_by() # 按指定字段进行排序

exists() # 判断queryset是否有数据
reverse() #  将queryset的顺序倒置,一般在order_by后使用。
distinct()  #  将queryset去重(每个字段的值都必须完全一样才会被去重)

2.双下划线查询

# 查询id>2的数据
res = models.Book.objects.filter(id__gt=2)
# 查询id>=2的数据
res = models.Book.objects.filter(id__gte=2)
# __lt、__lte 同理

# 查询在每个范围内的数据
res = models.Book.objects.filter(id__in=[1,2,3])
res = models.Book.objects.filter(id__in=range(1,6,2))
# 查询在100-1000价格的数据,包括10和100
res = models.Book.objects.filter(price__range=(100,1000))


# 模糊查询
res = models.Book.objects.filter(title__contains='三')
# 不区分大小写icontains
res = models.Book.objects.filter(title__icontains='三')

# 查询2020年1月出版的电影
res = models.Book.objects.filter(publish_date_year=2020,publish_date_month=1)

3.外键字段的增删改查

# 一对多 在book表增加一条数据
# 方式1
models.Book.objects.create(title='三国演义',price=333,publish_id=1)
# 方式2:通过增加或查找先得到一个obj对象
publish_obj = models.Publish.objects.create(name='东方出版社',addr='东京')
models.Book.objects.create(title='三国演义',price=333,publish=publish_obj)

# 对book表中的外键字段进行修改
models.Book.objects.filter(pk=1).update(publish_id=2)

# 将id为1的book出版社改为东方出版社
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

在为多对多创建关联记录时,由于django的orm是自动为我们创建的第三张表,我们的models类里也不存在这个类。所以我们不能直接以第三张表为对象去添加book和author的关联记录。

只能通过book _obj和author_obj下的方法来添加关联记录。

# 多对多    add、remove、set、clear
# 1.给书籍绑定作者关系
book_obj = models.Book.objects.filter(pk=1).first()
res = book_obj.author.all() #  可获得book_obj这条记录对应的作者对象。本质上在book_obj.author时进行了与book_author的连表操作,并获取到了结果。

# 为书籍与作者id为2和3进行绑定。
book_obj.author.append(2,3)
# 为某一书籍与作者david4和david3进行绑定
book_obj = models.Book.objects.filter(pk=1).first()
res = book_obj.author.all()
print(res)
print(res.query)
author_obj1 = models.Author.objects.filter(name='David4').first()
author_obj2 = models.Author.objects.filter(name='David3').first()
book_obj.author.add(author_obj1,author_obj2)
#remove方法与add方法同理
#set方法:接收一个元组或列表,有则删除、无则添加。
book_obj.author.set((1,))

# clear方法无需参数
book_obj.author.clear()

4.跨表查询

跨表查询分为子查询和联表查询。

子查询:将一张表的查询结果当做另外一张表的查询条件。

联表查询:先将两张有关联的表合并,然后再进行查询。

子查询和联表查询都有正向查询和反向查询的概念。

正向查询:跨表查询时外键字段在当前数据对象中则是正向,查询时按外键字段.

反向查询:跨表查询时外键字段不在当前数据对象中则是反向,查询时按表名小写_set.

注意:!!!外键字段在不在当前数据对象中以models中为准!!!一对一时无论正反都不需要加_set。

# 基于对象的跨表查询(子查询)
# 1.查询书籍id为1的出版社名称
book_obj = models.Book.objects.filter(pk=1).first()
# res = models.Publish.objects.filter(pk=book_obj.publish_id)
# print(res.first().name)
res = book_obj.publish.name
print(res)

#2.查询书籍id为2的所有作者
book_obj = models.Book.objects.filter(pk=2).first()
res = book_obj.author.all()
print(res)

#3.查询作者id为1的电话号码
author_obj = models.Author.objects.filter(id=1).first()
res = author_obj.author_detail
print(res.phone)

#4.查询出版社名称为东方出版社的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
res = publish_obj.book_set.all()
print(res)

#5.查询作者为david1的书籍
author_obj = models.Author.objects.filter(name='David1').first()
res = author_obj.book_set.all()
print(res)

#6.查询手机号为110的作者
author_detail_obj = models.AuthorDetails.objects.filter(phone=110).first()
res = author_detail_obj.author
print(res)
# 基于双下划线跨表查询(联表查询)
# django会将__自动识别为联表
# 1、查询书籍id为1的出版社名称
# 正向查询 
res = models.Book.objects.filter(id=1).values('publish__name')
print(res)
# 反向查询
res = models.Publish.objects.filter(book__id=1)
print(res)

# 2.查询书籍id为1的作者姓名和年龄
# 正向查询
res = models.Book.objects.filter(id=1).values('author__name','author__age')
# 反向查询
res = models.Author.objects.filter(book__id=1)
print(res)

# 3.查询作者是David1的年龄和手机号
# 正向查询
res = models.Author.objects.filter(name='David1').values('name','age','author_detail__phone')
print(res)
# 反向查询
res = models.AuthorDetails.objects.filter(author__name='David1')
print(res.first().phone)

# 4.查询书籍id为1的作者的手机号
# 正向查询
res = models.Book.objects.filter(pk=1).values('author__author_detail__phone')
print(res)

# 反向查询
res = models.AuthorDetails.objects.filter(author__book__id=1)
print(res.first().phone)

#!!!!! 只要表之间有关系,就可以一直用__进行联表操作。!!!!!!!

5.聚合查询

关键字aggregate

from django.db.models import Max, Min, Avg, Count, Sum
# 查询所有书的平均价格
res = models.Book.objects.aggregate(avg_num=Avg('price'))
print(res)
# 查询最贵的书的价格
res = models.Book.objects.aggregate(max_price=Max('price'))
print(res)
res = models.Book.objects.aggregate(Avg("price"),Max("price"), Min("price"),Count("pk"),Sum('price'))
print(res)

6.分组查询

关键字annotate

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

# 1.统计每一本数的作者的个数
res = models.Book.objects.all().annotate(author_num=Count('author')).values('title','author_num')
print(res)

# 2.统计出每个出版社卖的最便宜的书的价格
res = models.Publish.objects.all().annotate(min_price=Min('book__price')).values('name','min_price')
print(res)

#3.统计出不止一个作者的书
res =models.Book.objects.annotate(author_num=Count('author__id')).filter(author_num__gt=1)
print(res)

# 4.查询各个作者出的书总价格
res = models.Author.objects.annotate(total_price=Sum('book__price')).values('name','total_price')
print(res)


# 按照表中的一个字段分组
res = models.Book.objects.values('price').annotate()

7.F查询和Q查询

from django.db.models import F,Q

# F可以获取到每条记录对应的字段值
# 1.查询库存数大于销售数的书籍
res = models.Book.objects.filter(storage__gt=F('sales'))
print(res)
# 2. 为所有书籍价格增加100
res = models.Book.objects.update(price=F('price') + 100)
print(res)

# Q的用法
q = Q()
q.connector = 'or'  # q对象默认也是and关系  可以通过connector改变or
q.children.append(('title','python入门'))
q.children.append(('price',1000))
res = models.Book.objects.filter(q)
print(res)

猜你喜欢

转载自www.cnblogs.com/Ghostant/p/12169705.html