一。配置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. CodeForces - 1263E(线段树维护前缀和最值)

    题意 https://vjudge.net/problem/CodeForces-1263E 您要设计一个只有一行的打字机,这一行的长度是无限大,一开始可以认为每个字符都是空.您的打字机有一个光标只指 ...

  2. golang中的pflag示例

    现在晚上在家啃kubeadm的源码, 在啃源码前,pflag,viper,cobra这三件套好像是必须的, 那就先弄懂一下这三个套件的套路吧. 第一个,pflag. https://www.cnblo ...

  3. 2019.08.06模拟赛T2

    题目大意: 已知三个$n$位二进制数$A$,$B$,$C$. 满足: $A+B=C$ 它们二进制位中$1$的个数分别为$a$,$b$,$c$. 求满足条件的最小的$C$. Solution 唉,又是一 ...

  4. 给Java0基础的五个学习的思路?

    关于Java初学者来说,想学习Java教程,需求了解,根底打好才干学得更好,Java教程之学习Java的路线图的五个必经阶段,希望能对Java学习者有所帮忙. 第一个阶段-java根底阶段 1.jav ...

  5. js函数只执行一次,函数重写,变量控制与闭包三种做法

    一.情景需求 调用后台接口需要附带token信息,那么在每个请求的头部添加token的做法就不太优雅了:一个网站请求100次,那就得写添加100次token,假设某天接口有所变动,改起来就十分麻烦了. ...

  6. 通过组件实现相同group下字符串拼接

    实现效果 组件处理流程如下:         1 使用Sorter组件对ColA进行排序       2 使用expression组件进行如下配置 3 使用aggregate组件进行如下配置 ColA ...

  7. Anaconda更新报404:UnavailableInvalidChannel: The channel is not accessible or is invalid.error404

    Anaconda更新一直报错,修改为国内镜像也不好使,最终找到了未被屏蔽的镜像. 错误日志: UnavailableInvalidChannel: The channel is not accessi ...

  8. mysql数据库的十种查询方式及多表查询

    --mysql数据库的十种查询方式 -- (1)查询时起别名 SELECT id AS '编号',NAME AS '姓名',age AS '年龄' FROM student; -- (2)查询时添加常 ...

  9. jsp模板

    <%String path = request.getContextPath();String basePath = request.getScheme()+"://"+re ...

  10. 微信小程序反编译

    看到一个有意思的小程序,想了解是如何实现的,于是找了反编译方法. 安装adb驱动 百度安装adb驱动, 设计设置开发者模式,连接电脑. -> % adb devices List of devi ...