表操作及字段查询

模型层

单表操作

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对象的方法有:

  1. all()
  2. filter()
  3. exclude()
  4. order_by()
  5. reverse()
  6. distinct()

特殊的QuerySet

  1. values()       返回一个可迭代的字典序列
  2. values_list() 返回一个可迭代的元祖序列

返回具体对象的

  1. get()
  2. first()
  3. last()

返回布尔值的方法有:

  1. exists()

返回数字的方法有

  1. 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 的一个终止子句。用到的内置函数有Avg, Sum, Max, Min, Count。

分组查询

# 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可以帮我们取到表中某个字段对应的值来当作我的筛选条件,而不是我们认为输入的,实现了动态比较的效果。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)

 

posted @ 2019-09-19 20:51  kuanglinfeng  阅读(405)  评论(0编辑  收藏  举报