day55_9_19模型层的操作
一。配置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模型层的操作的更多相关文章
- 模型层ORM操作
一.ORM操作 1.关键性字段及参数 DateField 年月日 DateTimeField 年月日时分秒 auto_now: 每次操作改数据都会自动更新时间 auto_now_add: 新增数据的时 ...
- 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 ...
- {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询
Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...
- 模型层TP框架数据库的操作
在shop入口的文件下的HOME文件夹中使用模型层 第一步修改配置模块把数据库的各种链接做好,打开HOME中的conf文件夹中的config.php,找到Thinkphp文件加下的conf文件打开co ...
- 06.Django基础五之django模型层(二)多表操作
一 创建模型 表和表之间的关系 一对一.多对一.多对多 ,用book表和publish表自己来想想关系,想想里面的操作,加外键约束和不加外键约束的区别,一对一的外键约束是在一对多的约束上加上唯一约束. ...
- 模型层之ORM、数据库和单表操作
一.ORM简介 ORM是“对象-关系-映射”的简称,一般指持久化数据和实体对象的映射 1.1 什么是“持久化” 持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中( ...
- Django模型层之单表操作
Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软 ...
- Django模型层之更多操作
Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为 ...
- 1127 模型层orm表操作
目录 昨日回顾 模型层 1.配置测试脚本 1.1 应用下tests文件 1.2 新建任意名称文件 2. 数据的增删改查 2.1 创建数据 2.2 修改数据 2.3 删除数据 2.4查询数据 十三门徒 ...
随机推荐
- 移动网络游戏实现流程——并借此阐明pomelo在GitHub上各个项目间的关系
<!DOCTYPE html> 摘要:本文通过一个简易流程图介绍如何基于Cocos2d-x引擎和pomelo服务器框架开发一个移动网络游戏.并借此阐明pomelo提供的各个项目间的关系. ...
- 我的朋友&值得学习的大佬
@media only screen and (max-width: 360px) { #friedsGroup { columns: 1 !important; } } #MySignature{ ...
- JS---DOM---为元素解除绑定事件
解除绑定事件: 1.解绑事件 对象 .on 事件名字=事件处理函数--->绑定事件. 对象 .on 事件名字 = null . 注意:用什么方式绑定事件,就应该用对应的方式解除绑定事件. //1 ...
- acwing 517. 信息传递
地址 https://www.acwing.com/problem/content/description/519/ 有 n 个同学(编号为 1 到 n)正在玩一个信息传递的游戏. 在游戏里每人都有一 ...
- 11.web5
先补充点小知识: 关于jjencode 和 aaencode(颜文字) 1.什么是jjencode? 将JS代码转换成只有符号的字符串 2.什么是aaencode? 将JS代码转换成常用的网络表情 ...
- xpath:
from selenium import webdriverb = webdriver.Firefox()#路径读取方式一:# b.get(r"C:\我的代码\selenium自动化测试\t ...
- 《icra16_slam_tutorial_tardos.pdf》
icra16_slam_tutorial_tardos.pdf EKF: https://www.cnblogs.com/gaoxiang12/p/5560360.html 7. 小结 卡尔曼滤波是递 ...
- LG5202 「USACO2019JAN」Redistricting 动态规划+堆/单调队列优化
问题描述 LG5202 题解 \[opt[i]=xx+(cnt[i]-cnt[yy]<=0)\] 发现\(cnt[i]-cnt[yy] <= 0\)只能有两种取值 于是直接堆优化即可 \( ...
- cartographer 3D scan matching 理解
cartographer 3D scan matching没有论文和其它资料,因此尝试通过源码理解其处理方法,理解不当之处还请指正. 目录: 0.2D 匹配方法简介 1.real time corre ...
- 【STM32H7教程】第29章 STM32H7的USART串口基础知识和HAL库API
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第29章 STM32H7的USART串口基础知识和 ...