【django】模型类中数据的增删改查操作总结

news2024/10/5 21:23:40

在这里插入图片描述


文章目录

  • 一、数据库数据操作
  • 二、创建对象
  • 三、批量创建对象
    • 方法一:for循环迭代
    • 方法二:bulk_create()
  • 四、更新对象
    • save()默认更新所有的字段
    • 指定要更新的字段
    • 一次性更新多个对象
  • 五、查询对象
    • 1、管理器
    • 2、QuerySet
    • 3、检索全部对象
      • a、要注意:
    • 4、过滤
    • 5、查询单个对象
      • a、first方法
      • b、last方法
    • 6、排序
      • 注意:
    • 7、切片
  • 六、选择字段
    • 1、values
    • 2、value_list
    • 3、only
    • 4、defer
    • 注意
  • 七、条件查询
    • 1、exact(精确匹配)、iexact(精确匹配,不区分大小写)
    • 2、in
    • 3、range
    • 4、gt、gte、lt、lte
  • 八、条件组合
    • 1、AND
    • 2、OR
    • 九、聚合查询
  • 十、分组查询
      • 注意:
  • 十一、删除对象

一、数据库数据操作

一旦创建数据模型后,django自动给与一套数据库 抽象API,用来创建、检索、更新和删除对象。
为了方便调试,可以通过下面的命令进入django shell

python manage.py shell

使用这个命令进入的shell环境会包含当前的django项目的依赖,直接通过python命令进入的shell不会包含django依赖。

在日志等级debug=True,下面的代码可以打印除所有执行过的sql

from django.db import connection
print(connection.queries)

二、创建对象

创建一个模型对象,可以直接通过关键字参数实例化,然后调用save方法,将其存入数据库

from crm.models import Student
s=Student(**fields)
s.save()

这在幕后执行的INSERT 语句

注意:django在调用save()方法才会操作数据。save()方法没有返回值

还有一种创建对象并一步到位的create()方法
使用管理器上的create方法,会直接写入数据库
create方法会返回创建的对象

Student.objects.create(**fields)

三、批量创建对象

方法一:for循环迭代

批量创建对象可以利用上面的方法和for循环结合使用,但是效率比较低,会执行多条sql

data=[
    {"name":"james","age":18,"phone":"13888888888"},
    {"name":"kelai","age":22,"phone":"13688888888"},
    {"name":"kd","age":19,"phone":"13888888777"},
]

for item in data:
    s=Student(**item)
    s.save()

方法二:bulk_create()

bulk_create()方法可以有效的将提供的对象插入到数据库表(一般来说,不管多少个数据,只需要一条sql),它返回创建的对象列表

data=[
    {"name":"harden","age":18,"phone":"13888878228"},
    {"name":"curry","age":22,"phone":"13688883388"},
    {"name":"ad","age":19,"phone":"13888855577"},
]


Student.objects.bulk_create([
    Student(**(data[0])),
    Student(**(data[1])),
    Student(**(data[2]))
])

执行的sql语句:

print(connection.queries[-1])
{'sql': "INSERT INTO `t_student` (`name`, `age`, `phone`, `address`, `create_time`, `channel_id`) VALUES ('harden', 18, '13888878228', NULL, '2023-01-06 07:21:25.347180', NULL), ('curry', 22, '13688883388', NULL, '2023-01-06 07:21:25.347180', NULL), ('ad', 19, '13888855577', NULL, '2023-01-06 07:21:25.347180', NULL) RETURNING `t_student`.`id`", 'time': '0.000'}

但是需要注意

1、save()方法不会被调用,所以pre_save和post_save信号不会被发送
2、多对多关系也处理不了
3、多表继承模式,不能与子模型一起工作

四、更新对象

save()默认更新所有的字段

在幕后,执行了update语句

In [1]: from crm.models import Student

In [2]: from django.db import connection

In [3]: s=Student.objects.get(id=1)

In [4]: s.age=24

In [5]: s.save()

In [6]: print(connection.queries[-1])
{'sql': "UPDATE `t_student` SET `name` = 'kb', `age` = 24, `phone` = '15202629656', `address` = NULL, `create_time`
= '2023-01-01 10:41:36.822670', `channel_id` = NULL WHERE `t_student`.`id` = 1", 'time': '0.047'}

save()方法默认会更新所有的字段,可以在调用save方法的时候传递参数update_fields一个字段名称列表,
这样只有列表中的字段才会被更新。优点轻微的提升性能

指定要更新的字段

s.save(update_fields=['age','name'])

In [7]: s.age=28

In [8]: s.save(update_fields=['age','name'])

In [9]: print(connection.queries[-1])
{'sql': "UPDATE `t_student` SET `name` = 'kb', `age` = 28 WHERE `t_student`.`id` = 1", 'time': '0.016'}

一次性更新多个对象

如果想要统一设置查询集中的所有对象的某个字段,可以使用update()方法

Student.objects.update(sex=1)

五、查询对象

1、管理器

每一个模型都有一个默认的管理器,用来操作数据表,主要是构建QuerySet
默认的管理器的名称就是objects,直接通过模型类调用。

In [19]: Student.objects
Out[19]: <django.db.models.manager.Manager at 0x18af40aa2b0>

2、QuerySet

一个QuerySet表示数据库对象的一个集合,它可以迭代可以切片可以索引(不支持负数索引)
在SQL的层面上,对应的就是select语句

3、检索全部对象

直接管理器上调用all方法

In [20]: queryset=Student.objects.all()
In [21]: type(queryset)
Out[21]: django.db.models.query.QuerySet

方法all()返回一个包含所有数据的queryset对象。
可以通过打印queryset对象的query属性,来查看当前Queryet对象将要查询的sql语句

In [23]: print(queryset.query)
SELECT `t_student`.`id`, `t_student`.`name`, `t_student`.`age`, `t_student`.`phone`, `t_student`.`address`, `t_student`.`crea
te_time`, `t_student`.`channel_id` FROM `t_student` ORDER BY `t_student`.`id` ASC

In [24]: queryset
Out[24]: <QuerySet [<Student: kb>, <Student: kobe>, <Student: li>]>

a、要注意:

Queryset对象是惰性计算的,当通过管理器创建queryset的时候,并不会直接去数据库中查询,只有真正的对queryset进行计算的时候才会到数据库中查询。
什么时候?
迭代、切片、索引、打印

4、过滤

all():方法返回所有的数据,可以通过2个方法对queryset进行过滤
filter():返回新的Queryset,包含的对象满足给定的查询条件,对应where字句的正向条件
exclude():返回一个新的Queryset,包含对象不满足对给定查询参数,对应where字句的反向条件

例如:查询所有叫kobe的学生

Student.objects.filter(name='kobe')

如果是对整个查询进行操作,all可以省略

Student.objects.all().filter(name=''kobe)

同样的

Student.objects.all().exclude(name=''kobe")
Student.objects.exclude(name=''kobe")

5、查询单个对象

filter、exclude、all返回一个queryset,即使只有一个对象满足条件,这个时候queryset只包含一个元素

如果知道只有一个对象满足查询条件,可以在管理器上使用get方法,它会直接获取这个对象

Student.objects.get(pk=2)
Student.objects.get(id=2)

get方法中的条件如果过滤出多个对象会报错
如果没有这个对象也会报错

a、first方法

获取第一个对象,
对应ASC limit 1这个子句
注意:依赖于默认的排序

Student.objects.first()

b、last方法

获取最后一个对象
对应DESC LIMIT 1这个子句

Student.objects.last()

6、排序

排序是通过在queryset上调用order_by(*fields)、默认会按照主键排序,如果模型的Meta中定义了排序规则,则默认按其排序

class Meta:
	ordering=['-c_time']		模型类中加了表示默认排序

现在在student模型上进行查询,默认会使用c_time字段的desc排序

如果要清空查询集的默认排序,可以直接在查询集上调用order_by(),不用传任何参数

student.objects.order_by()

注意:

每次在Queryset上调用order_by方法都会覆盖之前的排序

In [39]: queryset
Out[39]: <QuerySet [<Student: kb>, <Student: kobe>, <Student: li>]>

查看sql语句

queryset.order_by('-name','age'):按照name降序,age升序

In [40]: q=queryset.order_by('-name','age')

In [41]: print(q.query)
SELECT `t_student`.`id`, `t_student`.`name`, `t_student`.`age`, `t_student`.`phone`, `t_student`.`address`, `t_student`.`create_time`,
`t_student`.`channel_id` FROM `t_student` ORDER BY `t_student`.`name` DESC, `t_student`.`age` ASC

7、切片

可以使用python序列切片的语法来获取部分数据,它等价于SQL的LIMIT与OFFEST子句

Student.objects.all()[:5] :获取前5条数据 等价于limit 5
Student.objects.all()[2:5] :从低3条开始取3条数据,等价于 limit 3 offset 2

前面所有的查询中,默认都是查询所有的字段。有时候只需要查询部分字段

六、选择字段

1、values

queryset.values(*fields)

返回一个queryset,这个queryset返回一个字段列表,而不是模型对象,参数fields指定select语句中,先要查询的字段。返回的字典中只会包含我们指定的字段;
如果不指定,则包含所有字段。

例如:不指定字段,返回所有的字段

Student.objects.all().values()

In [47]: q=Student.objects.all().values()


In [49]: q
Out[49]: <QuerySet [{'id': 1, 'name': 'kb', 'age': 20, 'phone': '15202629656', 'address': None, 'create_time': datetime.datetime(2023,
1, 1, 10, 41, 36, 822670, tzinfo=<UTC>), 'channel_id': None}, {'id': 2, 'name': 'kobe', 'age': 20, 'phone': None, 'address': None, 'cre
ate_time': datetime.datetime(2023, 1, 1, 15, 26, 3, 84534, tzinfo=<UTC>), 'channel_id': None}, {'id': 3, 'name': 'li', 'age': 20, 'phon
e': None, 'address': None, 'create_time': datetime.datetime(2023, 1, 1, 15, 26, 3, 84534, tzinfo=<UTC>), 'channel_id': None}]>

In [50]: q[0]
Out[50]: 
{'id': 1,
 'name': 'kb',
 'age': 20,
 'phone': '15202629656',
 'address': None,
 'create_time': datetime.datetime(2023, 1, 1, 10, 41, 36, 822670, tzinfo=<UTC>),
 'channel_id': None}

例如:指定字段,返回指定的字段

q=Student.objects.all().values('id','name')

In [52]: q=Student.objects.all().values('id','name')

In [53]: q
Out[53]: <QuerySet [{'id': 1, 'name': 'kb'}, {'id': 2, 'name': 'kobe'}, {'id': 3, 'name': 'li'}]>

In [54]: q[0]
Out[54]: {'id': 1, 'name': 'kb'}

2、value_list

queryset.value_list(*fields)

返回一个queryset,这个queryset返回一个嵌套元组的列表而不是模型对象,参数fields指定select语句中,先要查询的字段。返回的元组中只会包含我们指定的字段;
如果不指定,则包含所有字段。

例如:不指定字段,返回所有的字段

Student.objects.all().value_list()

In [3]: s=Student.objects.all()

In [7]: s2=s.values_list('name','age')

In [8]: s2
Out[8]: <QuerySet [('kb', 28), ('kobe', 20), ('li', 20), ('james', 18), ('kelai', 22), ('kd', 19), ('harden', 18), (
'curry', 22), ('ad', 19)]>

3、only

queryset.only(*fields)

返回queryset,这个queryset返回一个模型对象的列表。参数fields指定了我们想要查询的字段

注意:only一定会包含主键字段

q=Student.objects.all().only('name')

注意:
对only方法返回的模型对象,取没有指定的字段的值,django会再次去数据库中进行查询


In [3]: q=Student.objects.all().only('name')

In [4]: q
Out[4]: <QuerySet [<Student: kb>, <Student: kobe>, <Student: li>]>

In [5]: q[0]
Out[5]: <Student: kb>

In [6]: q[0].id
Out[6]: 1

In [7]: q[0].name
Out[7]: 'kb'

In [8]: q[0].age
Out[8]: 20

In [9]: print(connection.queries[-1])
{'sql': 'SELECT `t_student`.`id`, `t_student`.`age` FROM `t_student` WHERE `t_student`.`id` = 1 LIMIT
21', 'time': '0.015'}

In [10]: q
Out[10]: <QuerySet [<Student: kb>, <Student: kobe>, <Student: li>]>

In [11]: print(connection.queries[-1])
{'sql': 'SELECT `t_student`.`id`, `t_student`.`name` FROM `t_student` ORDER BY `t_student`.`id` ASC LI
MIT 21', 'time': '0.000'}

4、defer

defer(*fields)

q=Student.objects.all().defer('create_time')

defer方法中的参数fields指定了select语句中想要排除的查询字段,其他与only相同;
返回queryset,这个queryset返回一个模型对象的列表。

In [12]: q=Student.objects.all().defer('create_time')

In [13]: q
Out[13]: <QuerySet [<Student: kb>, <Student: kobe>, <Student: li>]>

In [14]: print(connection.queries[-1])
{'sql': 'SELECT `t_student`.`id`, `t_student`.`name`, `t_student`.`age`, `t_student`.`phone`, `t_stude
nt`.`address`, `t_student`.`channel_id` FROM `t_student` ORDER BY `t_student`.`id` ASC LIMIT 21', 'tim
e': '0.016'}


In [16]: q[0].create_time
Out[16]: datetime.datetime(2023, 1, 1, 10, 41, 36, 822670, tzinfo=<UTC>)

注意

only与defer返回的对象还是可以正常访问没有包含select语句中的字段,只是再次查询数据库

七、条件查询

在filter,exclude、get中可以接收参数,实现各种条件的查询

1、exact(精确匹配)、iexact(精确匹配,不区分大小写)

Student.objects.get(qq__exact=88888)
Student.objects.get(qq=88888)	简写

qq_exact=66666等价与qq=66666
默认情况下这个__exact省略
对应where语句中的相等条件

In [18]: Q=Student.objects.only('name').filter(name__iexact='KOBE')


In [20]: print(Q.query)
SELECT `t_student`.`id`, `t_student`.`name` FROM `t_student` WHERE `t_student`.`name` LIKE KOBE ORDER
BY `t_student`.`id` ASC

2、in

在一个给定的可迭代对象中,通常是一个列表,元组或者queryset

Student.objects.filter(age__in=[18,20])
对应where字句中的in

In [22]: q=Student.objects.filter(age__in=[18,20])

In [23]: print(q.query)
SELECT `t_student`.`id`, `t_student`.`name`, `t_student`.`age`, `t_student`.`phone`, `t_student`.`addr
ess`, `t_student`.`create_time`, `t_student`.`channel_id` FROM `t_student` WHERE `t_student`.`age` IN
(18, 20) ORDER BY `t_student`.`id` ASC

3、range

范围区间
对应sql中的between and

Student.objects.filter(age__range=[10,25])

4、gt、gte、lt、lte

gt:大于
gte:大于等于
lt:小于
lte:小于等于

Student.objects.filter(age__gt=18)

八、条件组合

1、AND

以下都是相同操作

Student.objects.filter(name='kobe',age=18)
Student.objects.filter(name='kobe').filter(age=18)
Student.objects.filter(name='kobe') & Student.objects.filter(age=18)

from django.db.model import Q
Student.objects.filter(Q(name='kobe') & Q(age=18))

等价于sql
where name= AND age=

2、OR

from django.db.model import Q


Student.objects.filter(name='kobe') | Student.objects.filter(age=18)
Student.objects.filter(Q(name='kobe') | Q(age=18))

等价于sql
where name= OR age=

九、聚合查询

需要导入:from django.db.models import Count,Sum,Avg,Max,Min

Count:统计数量

q8=Student.objects.aggregate(Count('id'))
print(q8)   

返回一个字典 {‘id__count’: 3}

可以指定聚合字段的值

q9=Student.objects.aggregate(count=Count('id'))
print(q9)       

返回一个字典 {‘count’: 3}

Sum:求和
Avg:求平均值
Max:求最大值
Min:求最小值

可以直接在查询集上调用count方法,会返回这个查询集的统计数量

q=Student.objects.count()

十、分组查询

一般分组会和聚合结合使用
django中需要使用values,annotate和聚合方法结合使用,

案例:
查询男女生各有多少人

Student.objects.values('sex').annotate(Count('sex'))

注意:

annotate默认使用主键进行分组
使用values时,要提前清空查询集上的order_by,不然结果是意料之外的

十一、删除对象

In [9]: s=Student.objects.get(id=1)

In [10]: s.delete()
Out[10]: (1, {'crm.Student': 1})

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/149669.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

01 踏上python之旅

Python是一种跨平台的、开源的、免费的、解释型的高级编程语言。它具有丰富和强大的库&#xff0c;能够把用其他语言制作的各种模块很轻松地连接在一起。所以被称为胶水语言。 python的应用领域&#xff1a; Web开发大数据处理人工智能自动化运维开发云计算爬虫游戏开发 解释…

【C语言】详解#define,#ifdef,#ifndef,#elif,#undef,以及相关运算符

1.明示常量 #define 预处理指令结尾不带&#xff1b;&#xff08;分号&#xff09;&#xff0c;在预编译的过程中使用宏的地方会进行展开&#xff0c;是用多少次就展开多少次&#xff0c;但是只替换 不计算&#xff0c;预处理器在发现程序中的宏后&#xff0c;会用宏等价的替换…

生物化学 SY002实验 最常用的酸spiric acid+阿司匹林Aspirin+从柳树皮得到水杨苷

阿司匹林已应用百年&#xff0c;成为医药史上三大经典药物之一。 小知识点&#xff1a;水杨酸的作用和阿司匹林的作用不同之处(抗凝)&#xff0c;使用时的胃损伤等 使用历史 埃及埃伯斯纸莎草纸中关于使用白柳树叶制成的混合物治疗发炎伤口的建议。&#xff08;因为柳叶和树…

软著申请你还不会?我是这样申请的

大家好&#xff0c;我是小悟 兄弟姐妹们&#xff0c;关于软著申请的话题&#xff0c;早前已经写过几篇文章的介绍了&#xff0c;包括软著的申请流程攻略和踩到被打回补正的坑&#xff0c;有兴趣的可以翻翻之前的文章&#xff0c;搜关键字【软著】就有。 私信的小伙伴来自各行…

9.Isaac教程-- Laikago 四足机器人的自主导航

Laikago 四足机器人的自主导航 开发智能机器人系统是一项多学科的工作&#xff0c;集成了动力学、控制、计算机视觉、人工智能等。 很难掌握所有这些领域。 即使你掌握了所有这些&#xff0c;也需要花费大量时间才能正确和稳健。 为了帮助机器人专家加速智能机器人的开发&…

笔试强训(12)

算法题1:计算日期到天数转换: 我们假设用例输入的是2022 1 1&#xff0c;那么我们对应的天数就是1天&#xff0c;我们就不应该在输出1月份的所有月数 public class Main {public static void main(String[] args) {Scanner scannernew Scanner(System.in);int yearscanner.next…

【uniapp小程序】上传图片

文章目录&#x1f34d;前言&#x1f34b;正文1、首先看官网uni.chooseImage(OBJECT) API 介绍2、案例代码演示3、效果展示&#x1f383;专栏分享&#xff1a;&#x1f34d;前言 本篇文章我们研究一下&#xff0c;在移动端开发过程中经常使用到的图片上传功能。在大多数小程序或…

ArcGIS基础实验操作100例--实验68注记符号化表达

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验68 注记符号化表达 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&am…

C语言入门(四)——分支语句

if语句 if/else语句 布尔代数 switch语句 if语句 目前我们写的简单函数中可以有多条语句&#xff0c;但这些语句总是从前到后顺序执行的。除了顺序执行之 外&#xff0c;有时候我们需要检查一个条件&#xff0c;然后根据检查的结果执行不同的后续代码&#xff0c;在C语言中可…

ResNet精读笔记(1)

introduction部分提出了几个问题 1.构建一个好的网络 &#xff1f; 把层堆起来吗 哈哈 跟堆汉堡一样 这里呢 我们都知道 当网络的层数变多之后 加深了 deep了 但是 就会带来 梯度消失或者爆炸的问题 这里 实在找不到好的图 本质上因为当层数多了之后 反向传播的计算里面是…

嵌入式:万字详解通信接口设计

文章目录UART接口UART的工作原理UART的功能和组成S3C2410A的UARTUART 操作&#xff08;1&#xff09;数据发送&#xff08;2&#xff09;数据接收&#xff08;3&#xff09;自动流控制&#xff08;4&#xff09;非自动流控制&#xff08;a&#xff09;接收数据操作&#xff08;…

【C++】模拟实现List的正向和反向迭代器(iterator、reverse_iterator)

文章目录1、搭建List的基本框架2、List中iterator和const_iterator3、反向迭代器revser_iterator1、搭建List的基本框架 STL中List容器底层是一个双向带头循环链表。 这里简单搭建一个List&#xff0c;下面我们不断完善。 思路&#xff1a; 1、List作为一个双向带头链表&…

excel函数公式:常用高频公式应用总结 下篇

公式6&#xff1a;根据身份证号码计算出生日期要从身份证号码中得到出生日期&#xff0c;这种问题对于从事人资行政岗位的小伙伴一定不陌生&#xff0c;公式也比较简单&#xff1a;TEXT(MID(A2,7,8),"0-00-00")就能得到所需结果&#xff0c;如图所示&#xff1a;要明…

vue+xlsx实现表格的导入导出:

文章目录一、vue前端使用xlsx和 xlsx-style 导出excel&#xff0c;并修改样式:1、改造后效果&#xff1a;2、实现&#xff1a;3、引入库xlsx-style4、excelUtil.js文件二、前端xlsx插件怎么设置导出的excel列宽自适应&#xff1f;2-1、效果2-2、效果三、xlsx插件&#xff0c;导…

Java语法六:线程安全以及死锁

前言&#xff1a; 接下来我们要了解一下&#xff0c;线程安全的集合类有哪些&#xff1f;什么是死锁以及怎么避免死锁问题。 1.多线程环境使用哈希表 1.1&#xff1a;HashTable 只是简单的把关键方法加上synchronized关键字。 public synchronized V put(K key, V value) p…

(1分钟速览)最近邻搜索--激光SLAM常用必杀技

学习kdtree的数据结构&#xff0c;和二叉树的思想大体上算是比较相似的。参考博客&#xff1a;https://blog.csdn.net/dive_shallow/article/details/113136145建树&#xff0c;一个递归的操作。这里的删除操作很好理解&#xff0c;分左子树和右子树两种情况。如果是左子树那么…

Go语言设计与实现 -- 内存对齐机制

什么是内存对齐 为了能让CPU可以更快的存取到各个字段&#xff0c;Go编译器会帮你把struct结构体做数据的对齐。所谓的数据对齐&#xff0c;是指内存地址是所存储数据的大小&#xff08;按字节为单位&#xff09;的整数倍&#xff0c;以便CU可以一次将该数据从内存中读取出来。…

每天五分钟机器学习:推荐系统中所有用户的损失函数是什么?

本文重点 我们分析机器学习算法都是从损失函数的角度来说的,为了找到最佳的参数θ,可以最小化损失函数,那么本节课程我们将学习基于内容的推荐系统的损失函数是什么? 数据集 我们将每一个电影称为样本,每个电影有两个特征x1、x2,其中x1表示该电影为恐怖片的程度,x2表…

测试开发 | 跨平台设备管理方案 Selenium Grid

Selenium Grid 是 Selenium 的三大组件之一&#xff0c;它可以在多台机器上并行运行测试&#xff0c;集中管理不同的浏览器版本和浏览器配置。通过将客户端命令发送到远程浏览器的实例, Selenium Grid 允许在远程计算机 (虚拟或真实) 上执行 WebDriver 脚本. 它旨在提供一种在多…

SSL证书的类型

SSL证书类型分3类&#xff1a;DV OV EV.域名型&#xff08;DV&#xff09;SSL证书: 信任等级一般&#xff0c;只需验证网站的真实性便可颁发证书保护网站。企业型&#xff08;OV&#xff09;SSL证书: 信任等级强&#xff0c;须要验证企业的身份&#xff0c;审核严格&#xff0c…