模型层
单表操作
1. all(): 查询所有结果
2. filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
3.get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
4. exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象。类似于取反。
5. values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
6.values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
7.order_by(*field): 对查询结果排序
print(models.Book.objects.order_by('price')) # 默认是升序 print(models.Book.objects.order_by('-price')) # 加负号就是降序
8.reverse(): 对查询结果反向排序,前面要先有排序才能反向
9. distinct(): 从返回结果中剔除重复纪录。去重的前提是一定要有完全重复的记录。
10.count(): 返回数据库中匹配查询(QuerySet)的对象数量。
11. first(): 返回第一条记录
12.last(): 返回最后一条记录
print(models.Book.objects.filter(pk=1).first())
13. exists(): 如果QuerySet包含数据,就返回True,否则返回False
操作分类:
返回QuerySet对象的方法有:
- all()
- filter()
- exclude()
- order_by()
- reverse()
- distinct()
特殊的QuerySet
- values() 返回一个可迭代的字典序列
- values_list() 返回一个可迭代的元祖序列
返回具体对象的
- get()
- first()
- last()
返回布尔值的方法有:
- exists()
返回数字的方法有
- count()
单表操作之双下滑查询
查看orm内部sql语句的方法有以下几点:
1.如果是queryset对象,那么我们可以使用点query方法直接查看该queryset的内部sql语句。
2.在django项目的配置文件中,配置一下参数即可实现所有的orm在查询的时候自动打印对应的sql语句。可直接把下面的这段代码复制到settings文件中。
1 LOGGING = {
2 'version': 1,
3 'disable_existing_loggers': False,
4 'handlers': {
5 'console':{
6 'level':'DEBUG',
7 'class':'logging.StreamHandler',
8 },
9 },
10 'loggers': {
11 'django.db.backends': {
12 'handlers': ['console'],
13 'propagate': True,
14 'level':'DEBUG',
15 },
16 }
17 }
models.Book.objects.filter(price__gt=200) # 查询价格大于200的书籍
__lt(小于),__gte(大于等于),__lte(小于等于)
models.Book.objects.filter(price__in=[200,300,666.66]) # 获取price是200或300或600.
models.Book.objects.filter(price__range=(200,800)) #获取price在200到800之间的,其中包括200和800.
# 查询书籍名字中包含p的
# 在原生sql语句中,要使用模糊匹配(like,%,-)。
models.Book.objects.filter(title__contains='p') # 仅仅只能获取title字段包含"ven"的
models.Book.objects.filter(title__icontains='p') # icontains对大小写不敏感
models.Book.objects.filter(title__startswith='三') # 获取title中以三开头的
models.Book.objects.filter(title__endswith='三') # 获取title中以三结尾的
models.Book.objects.filter(create_time__year='2017') # 查看出版日期的2017年的
多表操作
图书管理系统表创建
一对多:ForeignKey
一对一:OnoToOneField,可以用ForeignKey代替ForeignKey(unique=True)
注意:上面两个关键字所创建出来的字段会自动加上_id后缀
多对多:ManyToManyFiled
该字段并不会真正的在表中展示出来,它仅仅是一个虚拟字段,它的功能有两大类。
1.告诉orm自动创建第三种表。
2.帮助orm实现跨表查询。
测试环境的代码如下图:
一对多字段的增删改查
增.关键字为create()
update()
delete()
models.Publish.objects.filter(pk=2).delete() # 默认都是级联更新 级联删除
多对多字段的增删改查
增.关键字为create()
update()
remove()
#将某本书跟作者的关系全部清空
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.clear() # 清空当前书籍与作者的所有关系
小结:add(),set(),remove()都支持括号内传数字或者对象,并且可以传多个,但是set需要传一个可迭代对象。clear()内的括号不需要穿参数。
跨表查询
(1).一对一查询
正向:author---关联字段在author表里--->authordetail 按字段
反向:authordetail---关联字段在author表里--->author 按表名小写
(2).一对多查询
正向:book---关联字段在book表里--->publish 按字段
反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书
(3). 多对多查询
正向:book---关联字段在book表里--->author 按字段
反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书
小结:正向查询按外键字段,反向查询按表名小写。都是基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)
强调:在书写orm语句的时候 跟写sql语句一样,不要尝试着一次性写完,应该做到写一点看一点再写一点。
正向查找反向查找
# 1.查询手机号是130的作者年龄
# 正向
#res=models.AuthorDetail.objects.filter(phone=130).values('author__age')
# print(res)
# 反向
#res1=models.Author.objects.filter(author_detail__phone=130).values('age')
# print(res1)
# 2.查询书籍id是1 的作者的电话号码
# res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
# res1 = models.Book.objects.filter(pk=1).values('外键字段1__外键字段2__外键字段3__普通字段')
# print(res)
# 只要表里面有外键字段 你就可以无限制跨多张表
聚合查询(aggregate)
aggregate()是QuerySet
分组查询
# 3.统计每一本书的作者个数
from django.db.models import Max, Min, Count, Avg, Sum
# res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num','title')
# print(res)
# 4.统计出每个出版社卖的最便宜的书的价格
# res = models.Publish.objects.annotate(mmp = Min('book__price')).values('name','mmp')
# print(res)
# 5.统计不止一个作者的图书
# res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)
# print(res)
#只要是queryset对象 就可以无限制的调用queryset对象的方法!!!最最常用的就是对一个已经filter过滤完的数据 再进行更细化的筛选
F查询和Q查询
F查询
F查询的本质就是从数据库中获取某个字段的值。
# 1.把所有书名后面加上'新款',
from django.db.models.functions import Concat
from django.db.models import Value
ret3=models.Product.objects.update(name=Concat(F('name'),Value('新款')))
# Concat表示进行字符串的拼接操作,参数位置决定了拼接是在头部拼接还是尾部拼接,Value里面是要新增的拼接值
Q查询
filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询,就可以使用Q对象。
# 1.卖出数大于100 或者 价格小于100块的
from django.db.models import Q
models.Product.objects.filter(Q(maichu__gt=100)|Q(price__lt=100))
# 对条件包裹一层Q时候,filter即可支持交叉并的比较符
& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。
Q高级用法
q = Q()
q.connector = 'or' # 修改查询条件的关系 默认是and
q.children.append(('title__contains','三国演义')) # 往列表中添加筛选条件
q.children.append(('price__gt',444)) # 往列表中添加筛选条件
res = models.Book.objects.filter(q) # filter支持你直接传q对象 但是默认还是and关系
print(res)