一。配置settings。

  如果是queryset对象 那么可以点query直接查看该queryset的内部sql语句

  将以下代码放入settings中。就可以实现当使用orm时查看sql语句:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}

二。双下划线查询。

  在orm过滤查询中,有基于双下划线的查询,可以节省时间。

  1.大于:__gt

  可以匹配大于这个数值的数:

res = models.Book.objects.filter(price__gt=89)

  2.小于__lt

  匹配小于这个数值的数据:

res = models.Book.objects.filter(price__lt=89)

  3.大于等于__gte

  匹配大于等于这个数值的数:

res = models.Book.objects.filter(price__gte=89)

  4.小于等于__lte

  匹配小于等于这个数值的数:

res = models.Book.objects.filter(price__lte=89)

  5。__in

  匹配在后面这个数列中的所有值的数据/。

res = models.Book.objects.filter(price__in=[89,123,454])

  6.__range(x,y)

  匹配在这个范围中的所有数据。包括头和尾。

res = models.Book.objects.filter(price__range=[55,123])

  7.__contains

  模糊匹配,字段中包函这个字段的数据。

res = models.Book.objects.filter(title__contains='p')

  这个匹配区分大小写。下面这个方法不区分。

  8.__icontains

res = models.Book.objects.filter(title__icontains='P')

  9.__startswith

  匹配开头时这个数值的数据

res = models.Book.objects.filter(title__startswith='计')

  10.__endswith

  匹配结尾这个数值的数据

res = models.Book.objects.filter(title__endswith='互')

  11.__year

  匹配时间数据类型中年份为该年的数据:

res = models.Book.objects.filter(publish_date__year=2019)
res = models.Book.objects.filter(publish_date__month=9)

  当然,其中还有其他过滤日期的方法。

(自己理解): 

  对于像onetoonefield,foreign,manytomany等字段,都是 有母子之分的。

  也就是说这个虚拟字段在哪个表里,哪个表就是子表。

  而我们把根据子表查询母表时的动作叫正向查询。

    正向查询都是按找字段名查找。

  根据母表数据查询子表数据的动作叫反向查询。

    反向查询都是按照表名小写_set查找。

  得到的结果就是那个表的对象。

  而在1对1 的时候不需要加_set,只需要小写就行。

三。关于外键的增删改。

  1.一对多

  增:

  可以按照id值传入外键:

models.Book.objects.create(title='三国演义',price=189.99,publish_id=1)

  也可以将那个对象传入:

publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='红楼梦',price=999.99,publish=publish_obj)

  改:

  将id数字传入:

models.Book.objects.filter(pk=1).update(publish_id=3)

  可以将对象传入:

publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

  删:

  删除的时候,默认都是级联操作。也即是这个数据删除了它所关联的外键也删除。

models.Publish.objects.filter(pk=2).delete()

  2,多对多字段的增删改。

  增:

  增加操作多借助于add(),是一个正对query对象的方法。

#要给主键为1的书籍添加两个作者
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.authors)
# 对象点击多对多虚拟字段 会直接跨到多对多的第三张表
book_obj.authors.add(1)
book_obj.authors.add(2,3)

  add()也支持传入对象,添加对象:

author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
author_obj2 = models.Author.objects.filter(pk=3).first()
book_obj.authors.add(author_obj)
book_obj.authors.add(author_obj1,author_obj2)

  改:

  改操作借助于函数set()

  set支持传入数据:

将主键为1的书籍对象 作者修改为2,3
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.set([2,])
book_obj.authors.set([2,3])

  也支持传入对象:

author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
author_obj2 = models.Author.objects.filter(pk=3).first()
book_obj.authors.set([author_obj,])
book_obj.authors.set([author_obj, author_obj1, author_obj2])

  但是set中要是一个可迭代对象。但不能混合使用。

  删:

  删除操作使用的是remove函数:
  可以支持数字:

book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.remove(3)
book_obj.authors.remove(1,2)

  也支持对象:

author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
author_obj2 = models.Author.objects.filter(pk=3).first()
book_obj.authors.remove(author_obj)
book_obj.authors.remove(author_obj1,author_obj2)

  除了remove之外,还可以使用clear,将这个对象的所有联系都清空。

book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.clear() # 清空当前书籍与作者的所有关系

  这些操作也支持_set反向操作。

四。基于对象的跨表查询。

  多表查询的方法可以先将一个条件对象找到,通过他下面的虚拟字段或者起子表_set的方法获取表对象,在提取想要的信息。

  例子:

    查询作者是jason的家庭住址
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.author_detail.addr) 查询出版社是东方出版社出版的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
# print(publish_obj.book_set) # app01.Book.None
print(publish_obj.book_set.all()) 查询作者是jason的写过的所有的书籍
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set) # app01.Book.None
print(author_obj.book_set.all())

  注意,在获取了表之后,可以继续对其使用对表对象使用的一切方法。

五。基于双下划线的跨表查询。

  双下划线作用于任何关于表的字段的获取,其可以获取另一个它关联的表的字段数据。

  双下划线不分子母表。

  values()函数相当于原生sql语句中的select后面的值。其返回的也是一个queryset对象。其中传入的是字段

  例子:

查询jason这个作者的年龄和手机号
正向
res = models.Author.objects.filter
(name='jason').values('age','author_detail__phone')
print(res)
反向
res1 = models.AuthorDetail.objects.filter
(author__name='jason').values('phone','author__age')

  例子2:

# 查询手机号是130的作者年龄
# 正向
res = models.AuthorDetail.objects.filter(phone=130).values('author__age')
print(res)
# 反向
res1 = models.Author.objects.filter(author_detail__phone=130).values('age')

  只要表里有外键字段,就可以无限跨多张表:

res1 = models.Book.objects.filter(pk=1).values('外键字段1__外键字段2__外键字段3__普通字段')

六。聚合查询:

  聚合查询和sql原生语句差不都:

  1.Sum()求和

  2.Avg()求平均值

  3.Count()计数

  4.Max()最大值

  5.Min()最小值

from django.db.models import Max,Min,Count,Avg,Sum
res = models.Book.objects.aggregate(Sum('price'))
res1 = models.Book.objects.aggregate(Avg('price'))
res2 = models.Book.objects.aggregate(Count('price'))
res3 = models.Book.objects.aggregate(Max('price'))
res4 = models.Book.objects.aggregate(Min('price'))
res5 = models.Book.objects.aggregate(Max('price'),  
  Min('price'),Count('pk'),Avg('price'),Sum('price'))

  其中aggregate就是使用聚合函数,其中也支持双下划线跨表查询。

七。分组查询。

  分组查询使用annotate()

  这个函数中可以使用聚合函数,使用聚合函数产生的结果可以给他起别名,再通过value展示。

res = models.Publish.objects.annotate
  (mmp = Min('book__price')).values('name','mmp')

  如果annotate之前不使用value进行指定字段,就将这个表的id作为分组对象。指定了value就将value中的字段进行分组。

  例子:

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

八。f查询与q查询。

  f。将数据库中的数据取出转化成可操作的。

  当你需要查询一个值的数据两端都是数据库中的值时。可以使用f将后面那个值包起来,这样系统会根据记录一条条比对:

from django.db.models import F
res = models.Book.objects.filter(kucun__gt=F('maichu')) # 将书籍库存数全部增加1000
models.Book.objects.update(kucun=F('kucun')+1000)

  这个操作可以将数据库中本来的数据拿出来使用f操作进行转换,转换成课进行操作的对象:

 # 把所有书名后面加上'新款'
from django.db.models.functions import Concat
from django.db.models import Value
ret3 = models.Book.objects.update
    (title=Concat(F('title'), Value('新款')))
models.Book.objects.update(title = F('title')+'新款') # 不能这么写

  其中concat就是拼接字符串操作(再数据库中),而value就是将字符串转化成可操作的数据。

  q。将数据库的数据取出,转化成可进行逻辑比较的。

  如果需要将两个字段的数据一起匹配时可以使用q进行操作。

  例子:

from django.db.models import Q
查询书籍名称是三国演义或者价格是444.44
res = models.Book.objects.filter(title='三国演义',price=444.44) # filter只支持and关系
res1 = models.Book.objects.filter(Q(title='三国演义'),Q(price=444)) # 如果用逗号 那么还是and关系
res2 = models.Book.objects.filter(Q(title='三国演义')|Q(price=444))
res3 = models.Book.objects.filter(~Q(title='三国演义')|Q(price=444))
# 非操作。

  在q前面加上~表示非操作。

  衍生:

  当需要使用字符串作为表字段名进行操作的时候,可以使用q。

  也就是说不会提前知道字段名,只知道该字段是个字符串。

    # 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)

补充:

  1.在一对一字段中OnoToOneField操作可以用ForeignKey代替(ForeignKey(unique=True))

  2.虚拟字段除了关联第三张表之外,还能帮助orm跨表查询。

day55_9_19模型层的操作的更多相关文章

  1. 模型层ORM操作

    一.ORM操作 1.关键性字段及参数 DateField 年月日 DateTimeField 年月日时分秒 auto_now: 每次操作改数据都会自动更新时间 auto_now_add: 新增数据的时 ...

  2. Django 模型层 ORM 操作

    运行环境 1. Django:2.1.3 version 2. PyMysql: 0.9.3 version 3. pip :19.0.3 version 4. python : 3.7 versio ...

  3. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  4. 模型层TP框架数据库的操作

    在shop入口的文件下的HOME文件夹中使用模型层 第一步修改配置模块把数据库的各种链接做好,打开HOME中的conf文件夹中的config.php,找到Thinkphp文件加下的conf文件打开co ...

  5. 06.Django基础五之django模型层(二)多表操作

    一 创建模型 表和表之间的关系 一对一.多对一.多对多 ,用book表和publish表自己来想想关系,想想里面的操作,加外键约束和不加外键约束的区别,一对一的外键约束是在一对多的约束上加上唯一约束. ...

  6. 模型层之ORM、数据库和单表操作

    一.ORM简介 ORM是“对象-关系-映射”的简称,一般指持久化数据和实体对象的映射 1.1 什么是“持久化” 持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中( ...

  7. Django模型层之单表操作

    Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软 ...

  8. Django模型层之更多操作

    Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为 ...

  9. 1127 模型层orm表操作

    目录 昨日回顾 模型层 1.配置测试脚本 1.1 应用下tests文件 1.2 新建任意名称文件 2. 数据的增删改查 2.1 创建数据 2.2 修改数据 2.3 删除数据 2.4查询数据 十三门徒 ...

随机推荐

  1. Python添加邮件附件并通过邮件发送测试报告

    import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText c ...

  2. 查看oracle表空间内存

    查看oracle表空间内存 SELECT a.tablespace_name "表空间名", total "表空间大小", free "表空间剩余大小 ...

  3. DRF--ModelSerializer

    前戏 在之前我们写序列化器的时候,写的很low,遇到反序列化的有时候还需要重写该字段,用post请求的时候,还要重写create方法,用put请求的时候,还需要重写update方法.总而言之,写起来很 ...

  4. Redis思维导图

    Redis基本数据结构 1.String 1.1 数据结构 long len byte数组长度 long free 可用数组长度 char buff[] 数据内容 1.2 命令 键值:设置值通过字符串 ...

  5. 开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽!

    Spring Boot 算是目前 Java 领域最火的技术栈了,也是Java开发人员不得不掌握的技术,今天给大家整理了13个优质 Spring Boot 开源项目给大家参考,希望能够帮助到正在学习 S ...

  6. js常用但是不容易记住的代码

    <!-- iframe 自适应高度度 --><iframe src="__CONTROLLER__/showlist" frameborder="0&q ...

  7. 死磕 java同步系列之AQS终篇(面试)

    问题 (1)AQS的定位? (2)AQS的重要组成部分? (3)AQS运用的设计模式? (4)AQS的总体流程? 简介 AQS的全称是AbstractQueuedSynchronizer,它的定位是为 ...

  8. 如何将vim改造为python的IDE

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Jeffrey Wang PS:如有需要Python学习资料的小伙 ...

  9. springmvc字符编码过滤器CharacterEncodingFilter浅析

      一.在web.xml中的配置 <!-- characterEncodingFilter字符编码过滤器 --> <filter> <filter-name>cha ...

  10. Javascript中的几种函数

    (1)普通函数:这种函数是我们日常使用中用的最多的,用function关键字定义的函数.这也是符合多种语言定义的. function foo(){ // code } (2)箭头函数:用=>运算 ...