1.单表查询--必知必会的13条
函数名 |
说明 |
用法 |
返回值 |
注意事项 |
all() |
查询所有 |
Book.object.all() |
queryset |
- |
filter(*fields) |
条件查询 |
Book.object.filter(title="三国演义") |
queryset |
- |
get(*fields) |
条件查询 |
Book.object.get(title="三国演义") |
model_obj |
查询结果没有或者多个会报错 |
first() |
第一条 |
Book.object.filter(title="三国演义").first() |
model_obj |
- |
last() |
最后一条 |
Book.object.filter(title="三国演义").last() |
model_obj |
- |
order_by(*fields) |
排序 |
Book.objects.all().order_by("price") |
queryset |
.order_by("-price")倒叙order_by("-price","pub_date")多条件排序 |
exclude(*fields) |
排除 |
Book.objects.exclude(price=123) |
queryset |
- |
count() |
计数/查询条数 |
Book.objects.all().count() |
int |
- |
reverse() |
反向排序 |
Book.objects.all().order_by("title").reverse() |
queryset |
- |
exists() |
查询条件时候存在数据 |
Book.objects.all().exists() |
bool |
- |
values(*fields) |
返回需要的的字段 |
Book.objects.all().values("title","price") |
dict |
- |
values_list(*fields) |
返回需要的的字段的数据 |
Book.objects.all().values_list("title", "price") |
tuple |
- |
distinc() |
去重 |
Book.objects.all().values("title").distinc() |
dict / tuple |
一般会与values、values_list组合使用 |
2.单表查询--模糊查询
字段名 |
说明 |
用法 |
注意事项 |
__gt |
大于 |
__gte |
大于等于 |
__lt |
小于 |
__lte |
小于等于 |
__startwith |
以什么开始 |
__istartwith |
以什么开始不区分大小写 |
__endwith |
以什么结束 |
__iendwith |
以什么结束 不区分大小写 |
__contains |
包含 |
__icontains |
包含什么 不区分大小写 |
__in |
在什么里面的 |
__range |
在什么范围之间的 |
__year |
年份等与多少的 |
__month |
月份等于多少的 |
下面查询用到的表关系
class Book(models.Model):
nid = models.AutoField(primary_key=True) # 主键 自增
title = models.CharField(max_length=64,verbose_name="书籍名称") # 字符形式 最大长度32
price = models.DecimalField(max_digits=8,decimal_places=2,verbose_name="书籍价格") # 浮点型999999.99 最大长度 8位 小数点后2位
comment_count = models.CharField(max_length=32, verbose_name="评论数量")
poll_count = models.CharField(max_length=32, verbose_name="点赞数量")
pub_date = models.DateTimeField(verbose_name="出版日期") # "2012-12-12"
publish = models.ForeignKey(to="Publish",on_delete=models.CASCADE, verbose_name="正向关联出版社字段") # 级联删除
authors = models.ManyToManyField(to="Author", verbose_name="正向关联作者字段")
def __str__(self):
return self.title # queryset 显示的名称
class Meta:
verbose_name="书籍表"
class Publish(models.Model):
nid = models.AutoField(primary_key=True, verbose_name="主键")
name = models.CharField(max_length=32, verbose_name="出版社名称")
email = models.CharField(max_length=32, verbose_name="出版社邮箱")
def __str__(self):
return self.name # queryset 显示的名称
class Meta:
verbose_name = "出版社表"
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者名字")
age = models.IntegerField(verbose_name="年龄")
email = models.CharField(max_length=32, verbose_name="邮箱")
ad = models.OneToOneField(to="AuthorDrtail",on_delete=models.CASCADE,verbose_name="正向关联的作者详情字段")
def __str__(self):
return self.name # queryset 显示的名称
class Meta:
verbose_name = "作者表"
class AuthorDrtail(models.Model):
addr = models.CharField(max_length=32, verbose_name="作者住址")
tel = models.IntegerField(verbose_name="作者手机号")
def __str__(self):
return self.tel # queryset 显示的名称
class Meta:
verbose_name = "作者详情表"
3.表关联查询 基于对象的跨表查询
(子查询)
正向查询: 按字段 book.publish
Book ----------------------------- Publish
反向查询: 表名的小写_set.all()
# 查询python出版社的名字 和邮箱 书查出版社 -对多查询
book_obj = Book.objects.filter(title="python").first()
publish_obj = book_obj.publish
publish_obj.name
publish_obj.email
# 查询苹果出版社 出版的所有书籍名称
pub_obj = Publish.objects.get(name="苹果出版社")
publish_obj.book_set.all().values("title") # queryset
# 查询 jack 出版的所有书籍名称
author = Author.objects.filter(name="Jack").first()
author.book_set.all()
正向查询 book.author.all()
Book -----------------------------------Author
反向查询 表名小写_set.all() jack.book_set.all().values("age")
正向查询 author.ad
Author ----------------------- AuthorDetail
反向查询 ad.author : ad.表名小写
4.表关联查询 基于双下划线 __ 的跨表查询
(join 即 一次查询)
"""
一对多
正向查询 按字段
Book --------------------- Publish
反向查询 按表名小写
"""
# 查询书籍名为 python 的出版社的 名字 一对多
Book.objects.filter(title="python").values("publish__name") # 正向查询
Publish.objects.first(book__title="python").values('name') # 反向查询
# 查询 北京出版社 出版社的书籍 名称 一对多
Publish.objects.filter(name="北京出版社").values('book__title')
Book.objects.filter(pulish__name='北京出版社').values('title')
# 查询 python 这本书的作者的年龄 多对多
Book.objects.filter(title='python').values("authors__age")
Author.objects.filter(book__title='python').values('age')
return HttpResponse("查询成功")
# 查询 Jack 出版的书籍的 名称 多对多
Author.objects.filter(name='Jack').values("book__title")
Book.objects.filter(authors__name='Jack').values('title')
# 查询 Jack的手机号 一对一
Author.objects.filter(name='Jack').values("ad__tel")
AuthorDrtail.objects.filter(author__name="Jack").values("tel")
# 查询手机号为131 的作者的名字 一对一
AuthorDrtail.objects.filter(tel=131).values('author__name')
Author.objects.filter(ad__tel=131).values('name')
5. 连续跨表查询
# 查询 人民出版社 出版过的多有书籍的名字以及作者的名字
Publish.objects.filter(name="人民出版社").values("book__title","book__authors__name")
Book.objects.filter(publish__name="人民出版社").values("title","authors__name") Author.objects.filter(book__publish__name="人民出版社").values('book__title','name')
# 手机号以 151 开头的作者出版过的所有书籍名称以及出版社的名称
AuthorDrtail.objects.filter(tel__startwith=151).values('author__book__title',"author__book__publish__name")
Author.objects.filter(ad__tel__startwith=151).values("book__title",'book__publish__name')
6. 聚合 分组查询
- 导入集合函数
from django.db.models import Avg,Max,Sum, Min, Count
############## 聚合max min count min avg #########
from django.db.models import Avg,Max,Sum, Min, Count
# 查询多有书籍的平均价
Book.objects.all().aggregate(priceAvg=Avg("price")) # {"avg_price":123.00} 可以重命名
# 查询是多有书籍的个数
Book.objects.all().aggregate(c=Count("nid")) # {"c":4}
############## 分组(group by)查询 #########
# 查询书籍表每个出版社id以及对应的个数
# key : annotate 前 select 那个字段就按照 那个字段group by
Book.objects.values('publish_id').annotate(c=Count(1)) # 返回值
'''
select Count(1)m from book GROUP BY publish_id
'''
# 跨表查询
#查询出版社出版的名称以及对应的书籍平均价格
Publish.objects.values('name').annotate(avg_price=Avg("book__price")) # book__price Book表中的price
# 简单的写法 现联表查询出所有 再选择要筛选的字段
Publish.objects.annotate(avg_price='book_price').values('name',"avg_peice")
6. F(获取字段值) 与 Q (关系) 查询
################## F #################
from django.db.models import F, Q
# 查询 评论数 大于 点赞数的 书籍名称
Book.objects.filter(comment_count__gt=F(poll_count)).values("title")
# 查询评论数 大于 2倍点赞数的书籍名称
Book.objects.filter(commnet_count__gt=F(poll_count)*2).values("title")
# 批量有规律的更新 所有的书籍几个提升100 或者 提升1倍
Book.objects.all().update(price=100+F("price"))
Book.objects.all().update(price=F("price")*2)
################## Q 查询 #################
# 查询价格大于 300 或者 评论数大于3000的书籍
"""
运算符号 &与 |或 ~非
"""
Book.objects.filter(Q(price__gt=300)|Q(comment_count__gt=3000))
Book.objects.filter(~Q(Q(price__gt=300)|Q(comment_count__gt=3000)&Q(poll_count__lt=2000)))