Python Django 数据库的相关操作详解
作者:久醉绕心弦, 发布时间:2024-01-26 21:02:46
目录
前言
创建对象
方式一:
方式二:
更新对象
方式一:
方式二:
方式三:
查询
检索全部对象:
条件过滤:
方式一:
方式二:
检索单个对象:
总结
前言
上篇已经介绍过模型相关操作,并创建好了数据库及相关表字段,接下来将通过以下表在Django中进行表数据的增改查。
from django.db import models
class Student(models.Model):
"""
学生表
"""
name = models.CharField('学生姓名', max_length=200, unique=True, help_text='学生姓名')
gender = models.SmallIntegerField('性别', default='1', help_text='性别')
hobby = models.CharField('爱好', max_length=200, null=True, blank=True, help_text='兴趣爱好')
create_time = models.DateTimeField('创建时间', auto_now_add=True, help_text='创建时间')
class Meta:
"""
元数据,
"""
db_table = 'student' # 指定当前模型创建的表明,不写默认当前的模型名Student
verbose_name = '学生信息表' # 注释
verbose_name_plural = verbose_name # 指定为复数
ordering = ['-create_time'] # 使用创建时间倒序排序,不加-为正序
def __str__(self):
return self.name # 方便于调式,下面操作数据库时会体现出来
为了更方便调试,接下来通过控制台输出的形式进行相关操作,通过python manage.py shell命令会导入当前项目的django环境,在此前需要配置下日志输出的相关信息,将以下配置在settings.py文件中:
# 日志配置
LOGGING = {
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler'
}
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False
}
}
}
创建对象
前面介绍过一个模型类代表一张表,而类的实例则代表表中的一条记录,所以可以通过实例化模型类的形式来进行表记录创建,如下:
方式一:
实例化时创建传入字段,然后通过save方法保存
# 导入模型类
In [1]: from project2s.models import Student
# 实例化对象,传入必传字段
In [2]: s = Student(name='test',hobby='打篮球')
# 调用save方法保存到数据库,
In [3]: s.save()
# 输出内容如下:其底层还是使用的INSERT语句
(0.031) INSERT INTO `student` (`name`, `gender`, `hobby`, `create_time`) VALUES ('test', 1, '打篮球', '2021-11-10 12:49:13.814987') RETURNING `student`.`id`; args=('test', 1, '打篮球',
'2021-11-10 12:49:13.814987')
数据库插入成功:
方式二:
先实例化然后通过给属性赋值的形式,在通过save方法保存
In [2]: s1 = Student()
In [3]: s1.name = 'test1'
In [4]: s1.hobby = '唱歌'
In [5]: s1.save()
(0.031) INSERT INTO `student` (`name`, `gender`, `hobby`, `create_time`) VALUES ('test1', 1, '唱歌', '2021-11-10 13:13:41.183826') RETURNING `student`.`id`; args=('test1', 1, '唱歌', '
2021-11-10 13:13:41.183826')
数据库插入成功:
更新对象
更新时会检索对象的id是否存在,存在即修改。
修改实例属性,并通过save方法保存到数据库,底层使用UPDATE语句
方式一:
In [6]: s1.name = '测试'
In [7]: s1.save()
(0.031) UPDATE `student` SET `name` = '测试', `gender` = 1, `hobby` = '唱歌', `create_time` = '2021-11-10 13:13:41.183826' WHERE `student`.`id` = 2; args=('测试', 1, '唱歌', '2021-11-1
0 13:13:41.183826', 2)
数据库更新成功:
但只是修改了一个字段,可见UPDATE语句执行时修改了全部字段会造成性能问题,可以通过以下方式指定字段更新。
方式二:
save时通过update_fields指定字段
# 前面已经实例化过s2=Student(name='张三',hobby='唱歌')
In [11]: s2.name = '李四'
In [12]: s2.save(update_fields=['name'])
(0.047) UPDATE `student` SET `name` = '李四' WHERE `student`.`id` = 4; args=('李四', 4)
数据库更新成功:
方式三:
批量修改,通过模型类管理器objects,查询到所有记录,在调用update方法
In [2]: Student.objects.all().update(hobby='玩游戏')
(0.031) UPDATE `student` SET `hobby` = '玩游戏'; args=('玩游戏',)
Out[2]: 3
数据库更新成功:
查询
查询使用模型类的管理器objects,前面批量更改时已经用到过,当通过管理器查询,会生成一个QuerySet对象,代表了数据库中对象的集合,它可以迭代,支持切片,不支持负索引,还可以用list转换成列表。在sql的层面上个代表了select语句。
检索全部对象:
Stutent.objects.all() 得到的是QuerySet对象,模型类中定义了__ str __方法,输出了name。
In [4]: Student.objects.all()
Out[4]: (0.094) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` DESC LIMIT 21; a
rgs=()
<QuerySet [<Student: 李四>, <Student: 测试>, <Student: test>]>
# 转换成列表
In [5]: list(Student.objects.all())
(0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` DESC; args=()
Out[5]: [<Student: 李四>, <Student: 测试>, <Student: test>]
# 通过索引
In [6]: Student.objects.all()[0]
(0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` DESC LIMIT 1; args=()
Out[6]: <Student: 李四>
# 通过切片
In [5]: Student.objects.all()[:2] # 等价于 LIMIT 2
Out[5]: (0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` DESC LIMIT 2; ar
gs=()
<QuerySet [<Student: 李四>, <Student: 测试>]>
In [4]: Student.objects.all()[1:2] # 等价于 LIMIT 1 OFF SET 1
Out[4]: (0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` DESC LIMIT 1 OFF
SET 1; args=()
<QuerySet [<Student: 测试>]>
条件过滤:
方式一:
filter(**kwargs)
,包含满足给定查询参数的对象
In [4]: Student.objects.all().filter(name='李四')
Out[4]: (0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` WHERE `student`.`name` = '李四' ORDER BY `student
`.`create_time` DESC LIMIT 21; args=('李四',)
<QuerySet [<Student: 李四>]>
方式二:
exclude(**kwargs)
,不包含满足给定查询参数的对象
In [4]: Student.objects.all().exclude(name='李四')
Out[4]: (0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` WHERE NOT (`student`.`name` = '李四') ORDER BY `s
tudent`.`create_time` DESC LIMIT 21; args=('李四',)
<QuerySet [<Student: 测试>, <Student: test>]>
检索单个对象:
通过get方法如果检索超过1条数据会报错,所以一般配合pk使用
In [4]: Student.objects.all().get(pk=1)
(0.047) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` WHERE `student`.`id` = 1 LIMIT 21; args=(1,)
Out[4]: <Student: test>
返回第一条数据:
Stutent.objects.all().first()
In [5]: Student.objects.all().first()
(0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` DESC LIMIT 1; args=()
Out[5]: <Student: 李四>
返回最后一条数据:
Stutent.objects.all().last()
In [6]: Student.objects.all().last()
(0.031) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`create_time` ASC LIMIT 1; args=()
Out[6]: <Student: test>
由于模型类Meta内设置了通过时间倒序排序,所以查询结果会相反。
排序:
order_by(*fields)
,根据给定的字段进行排序。默认按照模型类中的Meta类来排序。
正序:
In [3]: Student.objects.all().order_by('name')
Out[3]: (0.047) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`name` ASC LIMIT 21; args=()
<QuerySet [<Student: test>, <Student: 李四>, <Student: 测试>]>
倒序:
In [4]: Student.objects.all().order_by('-name')
Out[4]: (0.047) SELECT `student`.`id`, `student`.`name`, `student`.`gender`, `student`.`hobby`, `student`.`create_time` FROM `student` ORDER BY `student`.`name` DESC LIMIT 21; args=()
<QuerySet [<Student: 测试>, <Student: 李四>, <Student: test>]>
来源:https://blog.csdn.net/weixin_42262081/article/details/121256006


猜你喜欢
- 一、将数据写入opengauss前提准备:成功opengauss数据库,并创建用户jack,创建数据库datasets。数据准备:所用数据以
- Python输出整数的方法:先使用str()函数将数字转换成字符串赋值给变量i,再用“if i.count('.') ==
- Mysql数据库是一个多用户,多线程的关系型数据库,是一个客户机/服务器结构的应用程序。它是对个人用户和商业用户是免费的.Mysql数据库具
- 如何在php中判断一个网页请求是ajax请求还是普通请求?你可以通过传递参数的方法来实现,例如使用如下网址请求:/path/to/pkphp
- 配置可能会随官方改变,本文仅供参考。1.下载安装GO的包到https://code.google.com/p/go/downloads/li
- 双向数据绑定指的是当对象的属性发生变化时能够同时改变对应的UI,反之亦然。换句话说,如果我们有一个user对象,这个对象有一个name属性,
- 本文实例为大家分享了Python3 Tkinkter + SQLite 实现登录和注册界面,供大家参考,具体内容如下Ubuntu14 + P
- 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义
- 【简介】django-admin.py是Django的一个用于管理任务的命令行工具。本文将描述它的大概用法。另外,在每一个Django pr
- 上文:成为一个顶级设计师的第二准则英文原文成为一个顶级设计师的第三准则:对比,对比,对比在设计里面,好的对比和你对颜色选择是密切相关的。对比
- 在事务性语句执行过程中,服务器将会进行额外的处理,在服务器执行时多个事务是并行执行的,为了把他们的记录在一起,需要引入事务缓存的概念。在事务
- 在TypeScript 项目中,我们经常需要使用声明一系列的ts类型。然而,手动写的效率实在太低,编写一个自动生成ts类型的工具可以解放生产
- PyQt5树形结构控件QTreeWidget简介QTreeWidget 类根据预设的模型提供树形显示控件。QTreeWidget 使用类似于
- 本文实例讲述了Go语言单链表实现方法。分享给大家供大家参考。具体如下:1. singlechain.go代码如下:////////////单
- 在进制学习时候,细心的小伙伴不免都发现unicher函数的存在,没错能够经常看到的,也就是关于进制的转化,那肯定有小伙伴要开心起来了,因为进
- 咱们用的os模块,读取文件的时候,其实他是含有__enter__ __exit__ 。 一个是with触发的时候,一个是退出的时
- 一、下载termux直接搜索Termux,进入官网: 点击箭头所指的标志,进入页面,往下划到下载版本,直接下最新版本,不推荐下载F
- 前言最近新来的小老弟问我,按照公司规定,电脑只有十分钟就锁屏,但是他不想让电脑在空闲十分钟后锁屏。于是我问他,是不是想挑战一下公司信息安全?
- 目录楔子paramikoSSHClient 的使用connect:实现远程服务器的连接与认证set_missing_host_key_pol
- list的话题的确不少,而且,在编程中,用途也非常多。有看官可能要问了,如果要生成一个list,除了要把元素一个一个写上之外,有没有能够让计