笔记整理:Django ORM基本数据操作

Django ORM基本数据操作

ORM是干啥用的

Django有一个显著的特点就是应用ORM理念处理数据,这使Django与其他开发语言或者框架明显区别开。ORM的意思是对象关系映射,Django ORM描述Django数据模型类与数据库之间的映射关系,通俗地讲就是一个类和一个数据库表进行对应,这使ORM在数据库层和业务逻辑层之间起到了桥梁的作用。

我的上一篇笔记创建数据模型里讲到,在Django的模型文件models.py每写一个类,数据库就会对应的生成一个数据库表。也就是说,我们根本不需要去写SQL语句就实现了表的创建。那么ORM就是为了免去写SQL语句而生的,ORM能实现的功能:一是生成数据库表,如数据库表的创建、修改、删除;二是惭怍数据库表的数据行,如数据行的增、删、改、查。注意,ORM不能创建数据库,需要在数据库管理系统中手动创建。

ORM如何使用

ORM使用步骤主要有如下5步:

1、在项目中使用的数据库管理系统中手动创建数据库

2、在项目的配置文件settings.py中设置数据库连接字符

3、在应用程序的模型文件models.py中编写继承于model.Model的数据模型

4、运行终端命令python manage.py makemigrations 、python manage.py migrate命令生成数据库表

5、根据需求使用ORM数据操作函数

以上步骤前4步在我的上一篇文章中都有详细讲解,本文主要讲述ORM数据操作的常见函数。我在学习Django ORM之前也在网上找过不少有关ORM的文章,讲的都是一个个函数怎么去传参或者作用是怎么样的,但是都忽略了告诉读者在哪里去调用,在这里给大家做一个解答。我们都知道我们在使用Django写项目的时候,最主要的逻辑部分都是写在视图函数文件views.py中的,而Django ORM映射实际上就是在我们编写的视图函数内部去调用ORM数据操作函数 ,去辅助我们的逻辑功能实现。

ORM数据操作常用函数

all() 返回符合条件的全部记录

models.Employee.objects.all()
"""
models表示应用目录下的模型文件,Employee是你在models文件下自己定义的数据类
所有的ORM数据操作函数都是在数据类名后面加objects再调用函数,下同
"""

filter() 返回指定条件的记录,filter后面的括号内为过滤条件,类似于SQL语句中where后面的条件语句

# 获取name字段为"铁蛋"的记录
models.Employee.objects.filter(name="铁蛋")

"""
filter后面括号内存放的过滤条件,针对数据表的字段过滤一般用“字段名+双下划线+条件名词”,括号内的过滤条件可以是多个,这些条件之间相当于SQL条件语句中and的关系。条件名词在ORM中主要包括contains、icontains、in、gt、lt、range、startswith、endswith、istartwith、iendswith等
"""

# 获取name字段包含"铁蛋"的记录
models.Employee.objcets.filter(name__contains="铁蛋")
# 获取name字段包含"tiedan"记录,icontains忽略大小写
models.Employee.objcets.filter(name__icontains="tiedan")
# 获取id等于10、20、66的记录
models.Employee.objcets.filter(id__in=[10,20,66])
# 获取1<id<10的记录
models.Employee.objcets.filter(id__gt=1,id_lt=10) # 两个条件的关系等同SQL中的and
# 获取1<=id<=66的记录
models.Employee.objcets.filter(id__range=[1,66]) # 此次range并非前闭后开

exclude() 反向筛选,与filter()用法相同,获得的结果相反

# 获取name字段不是"铁蛋"的记录
models.Employee.objcets.exclude(name="铁蛋")

order_by() 按order_by后面括号中的字段排序

# 筛选所有name不是"铁蛋"的记录,按name、id两个字段排序,默认升序
models.Employee.objects.exclude(name="铁蛋").order_by("name","id")
# 字段名前加负号'-',表示按该字段降序排列
models.Employee.objects.exclude(name="铁蛋").order_by("-name")

distinct() 去重,只去重记录集合中完全一样的记录(若表中有类似id的字段,则单独使用distinct()失去意义)

# 筛选所有name为"铁蛋"的记录并去重
models.Employee.objects.filter(name="铁蛋").distinct()

"""
注意:distinct()括号内不接受任何字段参数,要实现按指定字段去重应该结合values()、order_by()使用
而且,使用distinct()去重时跟随order_by()很重要!!!
"""

# 筛选所有name为"铁蛋"的记录并按email字段去重
models.Employee.objects.filter(name="铁蛋").values("email").distinct().order_by("email")

"""
distinct()函数有一个隐藏特性,当使用distinct()函数的时候,如果不使用order_by()函数做跟随,那么该函数会自动把当前表中的默认排序字段作为distinct的一个列,而这个默认排序的字段通常都是id字段,使得去重失败。因为在我们用Django创建数据库表的时候,Django除了会按照我们定义的类的属性创建字段以外,还会默认创建一个id字段。所以需要用order_by("字段名")来屏蔽这个特性
"""

以上5个函数的返回值都是QuerySet对象集。Django的QuerySet对象集本质上是对应于数据集的记录集合,QuerySet有一个特性就是“惰性”,即返回值为QuerySet的函数不会立即去数据库操作数据。当我们用到QuerySet的值时,它才会去数据库中获取数据,如遍历QuerySet、打印QuerySet、判断QuerySet是否有值时,它才会到数据中获取数据。

以下函数返回其他数据类型,可以理解成特殊的QuerySet类型

values() 返回一个字典类型序列,括号内的指定字段作为字典的键

obj = models.Employee.objects.values("id","name","email")
print(obj)


# 返回结果如下:
<QuerySet
[{"id":1,"name":"铁蛋","email":"tiedan@163.com"},{"id":2,"name":"建国","email":"jianguo@163.com"},{"id":3,"name":"富贵","email":"fugui@163.com"}]
>

values_list() 返回一个元组类型序列,函数括号内的字段用于指定元组的元素

obj = models.Employee.objects.values_list("id","name","email")
print(obj)


# 返回结果如下:
<QuerySet
[(1,"铁蛋","tiedan@163.com"),(2,"建国","jianguo@163.com"),(3,"富贵","fugui@163.com")]
>

get()、first()、last()、count() 返回单个对象,可以理解为返回数据表中的一条记录

# 返回id为1的记录,括号内为过滤条件
models.Employee.objects.get(id=1)
# 返回数据集的第一条记录
models.Employee.objects.first()
# 返回数据集的最后一条记录
models.Employee.objects.last()
# 返回数据集的长度
models.Employee.objects.count()
上一篇:预训练综述 Pre-trained Models for Natural Language Processing: A Survey 阅读笔记


下一篇:Django启航(三)Django模型