一。配置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封装发送信息到钉钉群

    发送信息到钉钉群 from dingtalkchatbot.chatbot import DingtalkChatbot class SendText: def __init__(self, webh ...

  2. Kali设置1920x1080分辨率

    root@kali:~# xrandr --newmode -hsync +vsync root@kali:~# xrandr --addmode Virtual1 1920x1080 root@ka ...

  3. wbr 标签实现连续英文字符的精准换行你知道吗?

    1.一般情况下的换行: word-break:break-all或者word-wrap:break-word <p>大家<wbr>想要<wbr>实现<wbr& ...

  4. poj 1979 Red and Black 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=1979 Description There is a rectangular room, covered with square tiles ...

  5. macOS 安装 Docker Desktop CE(转)

    现在基本上都使用docker进行部署项目,所以还是有必要学习下,关于docker的简介这里就不在描述,本文转载自https://yeasy.gitbooks.io/docker_practice/co ...

  6. Python变量内存管理

    目录 一.变量存哪了? 二.Python垃圾回收机制 2.1 引用计数 三.小整数池 一.变量存哪了? x = 10 当我们在p1.py中定义一个变量x = 10,那么计算机把这个变量值10存放在哪里 ...

  7. django--调用百度AI接口实现人脸注册登录

    面部识别----考勤打卡.注册登录.面部支付等等...感觉很高大上,又很方便,下面用python中的框架--django完成一个注册登录的功能,调用百度AI的接口,面部识别在网上也有好多教程,可以自己 ...

  8. js 的cookie问题

    获取时解码可以用decodeURIComponent(),代替 unescape() // 设置cookiefunction setCookie(name,value) { var Days = 30 ...

  9. 多线程通信的两种方式? (可重入锁ReentrantLock和Object)

    (一)Java中线程协作的最常见的两种方式: (1)利用Object的wait().notify()和notifyAll()方法及synchronized (2)使用Condition.Reentra ...

  10. javascript在数组的循环中删除元素

    在开发JavaScript应用的过程中,经常会遇到在循环中移除指定元素的需求. 按照常规的思路,就是对数组进行一个for循环,然后在循环里面进行if判断,在判断中删除掉指定元素即可. 但是实际情况往往 ...