03.Django-ORM
ORM
1. 数据库配置
配置使用sqlite3,mysql,oracle,postgresql等数据库
sqlite3数据库配置
DATABASES = {
'default': {
# 默认使用的数据库引擎是sqlite3,项目自动创建
'ENGINE': 'django.db.backends.sqlite3',
# 指定数据库所在的路径
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
mysql数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 表示使用mysql数据库引擎
'NAME': 'bwonline', # 数据库名字,先在mysql下创建好
'USER': 'root', # 数据库账号
'PASSWORD': '123456', # 数据库密码
'HOST': '127.0.0.1', # 数据库IP,留空表示"localhost"
'PORT': '3306', # 数据库端口
}
}
2. ORM表模型
一对一(one-to-one)概念:
实质就是在主外键(foreign key)的关系基础上,给外键加了一个unique=True的属性。
一对多(one-to-many)概念:
就是主外键关系(foreign key)
多对多(many-to-many)概念:
(ManyToManyField)自动创建第三张表,也可以手动创建第三张表:两个foreign key
3. ORM操作
3.1 QuerySet
QuerySet 可迭代 可切片
Django的QuerySet 对应于数据库的记录,通过设定的条件进行过滤
QuerySet 的惰性机制:
Table.objects.all()或者.filter()语句不会运行任何的数据查询
只有调用QuerySet的时候才会执行SQL语句
要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.
为了验证这些,需要在settings里加入 LOGGING(验证方式)QuerySet 的cache:
# queryset是具有cache的
# 当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行(evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,你不需要重复运行通用的查询。
obj=models.Book.objects.filter(id=3)
# for i in obj:
# print(i)
## models.Book.objects.filter(id=3).update(title="GO")
## obj_new=models.Book.objects.filter(id=3)
# for i in obj:
# print(i) #LOGGING只会打印一次 # 简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些数据!为了避免这个,可以用exists()方法来检查是否有数据:
obj = Book.objects.filter(id=4)
# exists()的检查可以避免数据放入queryset的cache。
if obj.exists():
print("hello world!") # 当queryset非常巨大时,cache会成为问题
#处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法来获取数据,处理完数据就将其丢弃。
bjs = Book.objects.all().iterator()
# iterator()可以一次只从数据库获取少量数据,这样可以节省内存
for obj in objs:
print(obj.name)
#BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
for obj in objs:
print(obj.name) #当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询
总结:
queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。
使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能
会造成额外的数据库查询。
3.2 增
一对一信息的创建
|---> create方式
|---> save方式
一对多信息的创建
|---> create方式
|---> save方式
多对多信息的创建
|---> 使用model.ManyToManyField()会自动创建第三张表
|---> 手动创建多对多信息表
|---> create方式
|---> save方式
3.3 删
#filter返回一个QuerySet对象,filter里可以设定多个过滤条件
Book.objects.filter(id=1).delete()
3.4 改
save() # 将所有属性重新设定一遍,效率低
update()# 直接设置对象的属性
# update()是QuerySet对象的一个方法
# get返回的是一个model对象,其没有update方法
3.5 查
all() # 获取所有数据 支持切片操作(不支持负索引)返回QuerySet对象
get(id=1) # 获取id=1的一组数据(若获取了多组数据,就会报错)返回model对象
filter(sex="男") # 筛选sex="男"的数据,所有符合条件的数据都会返回,返回QuerySet对象
exclude(sex="女")# 排除sex="女"的数据,返回不符合条件的所有数据,返回QuerySet对象
3.5.1 对象查询
正向查找:子表查询主表
反向查找:主表查询子表
class Author(model.Model):
name = models.CharField(max_length=64)
class Book(model.Model):
bookName = models.CharField(max_length=64)
author = models.Foreignkey("Author",related_name="book", on_delete=model.CASCADE)
# 正向查找
book = Book.objects.get(id=1)
author = book.author
# 反向查找
author - Author.objects.get(id=1)
# 方式一:主表.子表_set() 返回QuerySet对象
author.Book_set().all()
# 方式二:通过在外键中设置related_name属性值既可
author.book.all()
3.5.2 双下划线(__)查询
条件查询与对象查询对应,是在filter,values等方法中通过__来明确查询条件
# 单表条件查询
|---> startswith # 指定开头的匹配条件
|---> istartswith # 指定开头的匹配条件(忽略大小写)
|---> endswith # 指定结束的匹配条件
|---> iendswith # 指定结束的匹配条件(忽略大小写)
|---> lt # 小于某个值
|---> gt # 大于某个值
|---> in # 在list中匹配
|---> contains # 包含
|---> icontains # 包含(忽略大小写)
|---> range=(1,4) # 在某个范围内
# 多表条件查询
|---> #正向查找之一对一查询
|---> #正向查找之一对多查询
|---> #反向查找之一对多查询
|---> #反向查找之多对多查询
3.5.3 聚合函数
# 使用聚合函数需要导入
from django.db.models import *
# Avg() 求平均值
# Count() 统计个数 参数distinct=True 去重
# Max() 获取最大值 Min() 求最小值
# Sum() 求和
聚合查询:aggregate() 返回字典
- 格式:变量=表.objects.aggregate(聚合函数名('字段名'))
- 默认的键名:字段名__聚合函数名
分组查询: annotate() 返回queryset对象
- 格式:变量=表.objects.values('字段名').annotate(聚合函数名('字段名'))
- values: 分组。类似于先筛选一遍
F查询: 专门取对象中某列值的操作 支持加减乘除操作
from django.db.models import F
Table.objects.all().updata(num=F("num")+10)
Q查询: 构建搜索条件(匹配条件)
- Q对象可以组合使用
&,|操作符,当一个操作符用于两个Q对象时,会产生一个新的Q对象 - 可以用
~操作符放在表达式前面表示否定,也可允许否定与不否定形式的组合 - Q对象可以与关键字参数查询一起使用,Q对象放在关键字查询参数的签名
from django.db.models import Q
Table.objects.filter(~Q(sex="男")&Q(age=18))
4. 查询数据库性能优化
1. 使用values指定查询字段避免使用all()
结果是一个QuerySet ,但内部却是一个字典
2. select_related主动联表查询
在第一次查询的时候,在all()前面加上一个select_related来做主动的联表查询;
一次联表查询多张数据表中,格式为:select_related("table1__table2");
一次联表查询一张数据表中的多个字段时,每个字段使用逗号隔开;
联表查询也会降低性能。
3. prefetch_related非主动联表查询
prefetch_related()方法既非主动联表查询,又不会运行很多查询语句的一种方案
使用prefetch_related每多查询一个字段,会在原来的基础上多查询一次数据库
4. only方法
执行查询操作的时候加上only方法,其查询结果还是一个对象集合
查询时加上only方法,only方法中添加哪个字段就只查询这个字段的相关数据
加only参数是从查询结果中只取某个字段
5. defer方法
defer方法是从查询结果中排除某个字段
03.Django-ORM的更多相关文章
- Django学习之十四:Django ORM继承关系
目录 Django ORM继承关系 1. SINGLE_TABLE(django好像不支持) 2. TABLE_PER_CLASS 3. JOINED 4. 代理继承 Django ORM继承关系 参 ...
- django orm查询和后端缓存的使用
django orm 查询 1 字段后(db_column='age') (null=True)#表示数据库里面的该字段数据可以为空 (blank=True)#表示前端表单提交的时候可以为空 (db_ ...
- django orm总结[转载]
django orm总结[转载] 转载地址: http://www.cnblogs.com/linjiqin/archive/2014/07/01/3817954.html 目录1.1.1 生成查询1 ...
- Django ORM - 001 - 外键表查询主表信息
开始用Django做web开发,我想大家都会遇到同样的问题,那就是如何高效快速的查询需要的数据,MVC都很简单,但是ORM折腾起来就有些费时间,我准备好好研究下Django ORM,所以会有一个系列的 ...
- Django ORM 中的批量操作
Django ORM 中的批量操作 在Hibenate中,通过批量提交SQL操作,部分地实现了数据库的批量操作.但在Django的ORM中的批量操作却要完美得多,真是一个惊喜. 数据模型定义 首先,定 ...
- Django ORM 查询管理器
Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...
- Django ORM模型的一点体会
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. 使用Python的Django模型的话,一般都会用它自带的ORM(Object-relational ma ...
- 数据库表反向生成(二) Django ORM inspectdb
在前一篇我们说了,mybatis-generator反向生成代码. 这里我们开始说如何在django中反向生成mysql model代码. 我们在展示django ORM反向生成之前,我们先说一下怎么 ...
- Django ORM那些相关操作
一般操作 https://docs.djangoproject.com/en/1.11/ref/models/querysets/ 官网文档 常用的操作 <1> all() ...
- django orm 及常用参数
一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...
随机推荐
- 首次使用AWS服务器EC2
AWS有一年的免费套餐,这个便宜我得占. 申请的时候需要填写银行卡,AWS暂不支持储蓄卡,只好绑信用卡了. 创建EC2实例之后,下一个要解决的问题就是远程root访问. 1. 修改安全组设置 2. s ...
- Lasso回归
Lasso 是一个线性模型,它给出的模型具有稀疏的系数(sparse coefficients).它在一些场景中是很有用的,因为它倾向于使用较少参数的情况,能够有效减少给定解决方案所依赖变量的个数.因 ...
- LTE网络概述
LTE主要由两部分组成:无线接入技术演进(E-UTRAN)+系统架构演进(SAE):其中,SAE主要含有的是演进型分组交换核心网(EPC),其控制处理部分为移动性管理实体(MME),数据承载部分称为业 ...
- NetCore项目实战篇05---添加Ocelot网关并集成identity server4认证
今天来给我们的项目增加API网关,使用Ocelot. 它是系统暴露在外部的一个访问入口,这个有点像代理访问的家伙,就像一个公司的门卫承担着寻址.限制进入.安全检查.位置引导.等等功能.同时我们还要在网 ...
- salesforce零基础学习(九十七)Event / Task 针对WhoId的浅谈
我们在Sales Cloud中经常会创建顾客,如果针对TO C业务,会启用个人顾客,比如针对车企行业,有一些场景是需要卖给个人的,而不只是企业采购.当通过打电话或者其他的场景有潜在客户并且转换成客户以 ...
- 第十章:Python高级编程-多线程、多进程和线程池编程
第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...
- Day_11【集合】扩展案例2_使用普通for循环获取集合中索引为3的元素并打印,统计集合中包含字符串"def"的数量,删除集合中的所有字符串",将集合中每个元素中的小写字母变成大写字母def",
分析以下需求,并用代码实现 1.定义ArrayList集合,存入多个字符串"abc" "def" "efg" "def" ...
- 爬虫系列 一次采集.NET WebForm网站的坎坷历程
今天接到一个活,需要统计人员的工号信息,由于种种原因不能直接连数据库 [无奈].[无奈].[无奈].采取迂回方案,写个工具自动登录网站,采集用户信息. 这也不是第一次采集ASP.NET网站,以前采集的 ...
- Git使用教程之新手也能看懂(一)
首先我写这篇文章的初衷是因为 有一段时间没用Git了,现在突然用起来,很多命令都忘记了,导致去上网查了各种资料和文档(其中廖雪峰老师的文章给我的帮助很大,非常感谢!),花费了大量的时间,等于是又重新学 ...
- [hihoCoder1231 2015BeijingOnline]求圆与多边形公共部分的周长
题意:如题 思路:离散.将所有交点求出来,相当于将多变形的边切成了很多条元边,对每条元边,有两种情况 在圆内,答案加上此边长 在圆外,答案加上此边相对于圆心的"有向转弧" #inc ...