Django ORM详解

Django ORM详解

ORM

ORM,对象关系映射, 对象和关系之间的映射。这样就可以使用面向对象的方式来操作数据库中的表。

ORM 的主要目的是将数据库操作抽象成面向对象的操作,使得开发者可以使用 Python 代码而不是 SQL 语句来执行数据库操作

Model模型

字段类型

字段类 说明
AutoField 自增的整数字段。 如果不指定,django会为模型类自动增加主键字段
BooleanField 布尔值字段,True和False 对应表单控件CheckboxInput
NullBooleanField 比BooleanField多一个null值
CharField 字符串,max_length设定字符长度 对应表单控件TextInput
TextField 大文本字段,一般超过4000个字符使用 对应表单控件Textarea
IntegerField 整数字段
BigIntegerField 更大整数字段,8字节
DecimalField 使用Python的Decimal实例表示十进制浮点数。max_digits总位数, decimal_places小数点后的位数
FloatField Python的Float实例表示的浮点数
DateField 使用Python的datetime.date实例表示的日期 对应控件为TextInput,关联了一个Js编写的日历控件 auto_now=True 每次修改对象被保存save()时,自动设置为当前时间。更新场景(最后修改时间) auto_now_add=True 仅在对象第一次创建时,自动设置为当前时间,之后不在更改(创建时间)
TimeField 使用Python的datetime.time实例表示的时间,参数同上
DateTimeField 使用Python的datetime.datetime实例表示的时间,参数同上
FileField 一个上传文件的字段
ImageField 继承了FileField的所有属性和方法,但是对上传的文件进行校验,确保是一个有效的图片
EmailField 能做Email检验,基于CharField,默认max_length=254
GenericIPAddressField 支持IPv4、IPv6检验,缺省对应文本框输入
URLField 能做URL检验,基于CharField,默认max_length=200

缺省主键

缺省情况下,Django的每一个Model都有一个名为 id 的AutoField字段,如果显式定义了主键,这种缺省主键就不会被创建了

字段选项

字段 说明
db_column 表中字段的名称。如果未指定,则使用属性名
primary_key 是否主键
unique 是否是唯一键
default 缺省值。这个缺省值不是数据库字段的缺省值,而是新对象产生的时候被填入的缺省值
null 表的字段是否可为null,默认为False
blank Django表单验证中,是否可以不填写,默认为False
db_index 字段是否有索引
verbose_name 可视化的名字,即字段的可读名称
choices 提供枚举值,每一项枚举值是二元组 (value, label),其中 value 是存储在数据库中的实际值,而 label 用于在界面上显示

关系类型字段类

字段 说明
ForeignKey 外键,表示一对多 to_field 选项表示关联到主表的哪个字段,默认使用主键 on_delete 选项表示选择哪个外键约束操作 ForeignKey('production.Manufacturer') 自关联 ForeignKey('self')
ManyToManyField 表示多对多 Django会自动创建第三张表来管理这个多对多的关系,这个中间表包含了两个外键,分别指向参与多对多关系的两个模型。 默认情况下,这个表的名字是 <model>_tablename 如果想要自定义中间表,通过 through 参数指定一个自定义的中间模型
OneToOneField 表示一对一

管理器

管理器非常重要,有了它才能操作数据库。即增删改查

每一个非抽象的Model类必须有一个Manager实例。如果不指定,Django会默认指定一个Manager,就是属性objects。

Django查询

查询集

如果查的是一批数据,那么返回的是一个结果的集合,即查询集,是 django.db.models.query.QuerySet 的实例,也是可迭代对象。

查询集是惰性查值,创建查询集不会带来任何对数据库的访问,直到调用方法使用数据时,才会访问数据库。

每一个查询集都包含一个缓存,来最小化对数据库的访问。首次对查询集遍历求值时,会发生数据库查询,Django会把查询的结果存在这个缓存中,并返回请求的结果,接下来对改查询集求值将使用缓存的结果。

限制查询集

限制查询集,即查询集对象可以直接使用索引下标的方式(不支持负索引),相当于SQL语句中的 limit 和 offset 子句,在分页功能中适用。

下例方法中,如果返回值如果是QuerySet类型,可以链式调用

结果集方法

名称 返回值类型 说明 举例
all() QuerySet 返回全部数据 Employee.objects.all()
filter() QuerySet 过滤,返回满足条件的数据,可以指定多条过滤条件 Employee.objects.filter(pk=10010).values()
exclude() QuerySet 排除,排除满足条件的数据 Employee.objects.exclude(emp_no=10001)
order_by() QuerySet 排序,注意参数是字符串,'-' 表示降序 Employee.objects.exclude(emp_no=10002).order_by('-pk')
values() QuerySet 返回集合内的元素是字典,字典内是字段和值的键值对 Employee.objects.values()

返回单个值的方法

名称 说明 举例
get() 严格返回满足条件的单个实例对象 如果未能返回对象则抛出DoesNotExist异常; 如果能返回多条,抛出MultipleObjectsReturned异常 Employee.objects.filter(pk=10010).get()
count() 返回当前查询的总条数 Employee.objects.count()
first() 返回第一个实例对象 Employee.objects.first()
last() 返回最后一个实例对象 Employee.objects.exclude(pk=10010).last()
exist() 判断查询集中是否有数据,如果有则返回True Employee.objects.exists()

字段查询(Field Lookup)表达式

字段查询表达式可以作为filter()、exclude()、get()的参数,实现where子句

语法:属性名称__比较运算符 = 值 (双下划线)

名称 举例 说明
exact filter(isdeleted=False) filter(isdeleted__exact=False) 严格等于,可省略不写
contains exclude(title__contains='天') 是否包含,大小写敏感 等价于like binary '%天%' 模糊匹配效率很低
startswith endswith filter(title__startswith='天') 以什么开头或结尾,大小写敏感
isnull isnotnull filter(title__isnull=False) 是否为null
iexact icontains istartswith iendswith i 的意思是忽略大小写
in filter(pk__in=[1,2,3,100]) 是否在指定范围数据中
gt、gte lt、lte filter(id__gt=3) filter(pk__lte=6 ) filter(pub_date__gt=date(2000,1,1)) 大于、小于等
year month day week_day hour minute second filter(pub_date__year=2000) 对日期类型属性处理

Django增删改

增加:create(字段名1=value, 字段名2=value, ...)

更新:update(字段名=value)

删除:delete()

相关推荐
jiaoxingk3 分钟前
异步协程中基于 aiomysql 的异步数据库操作
数据库·爬虫·python
qq_38413684418 分钟前
慢sql处理流程和常见案例
数据库·解决方案·mysql8·慢sql
kngines23 分钟前
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.2 数据分组与透视(CUBE/ROLLUP/GROUPING SETS)
数据库·postgresql·数据分析·rollup·grouping·cube
xuanjiong41 分钟前
Javaweb项目--Mybatis,导入com.mysql.cj.jdbc.Driver时报错,Cannot resolve class ‘Driver‘
数据库·mysql·mybatis
怀君1 小时前
Flutter——数据库Drift开发详细教程(一)
数据库·flutter·oracle
夏子曦1 小时前
EF Core 中,AsEnumerable 和 AsQueryable 的区别
数据库
试着1 小时前
【数据库】四种连表查询:内连接,外连接,左连接,右连接
数据库·mysql·oracle
没有感情的一匹码1 小时前
MongoDB 整合SpringBoot
数据库·spring boot·mongodb
简单的话*1 小时前
MySQL连接报错处理:1130-host ... is not allowed to connect to this MySql server
数据库·mysql
_extraordinary_2 小时前
MySQL 复合查询
android·数据库·mysql