热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Django_ORM框架_关联字段_CRUD操作

ORM框架_关联字段_抽象模型类_CRUD操作CRUD的含义数据写入查询数据更新数据删除数据关联字段定义抽象模型类设置默认排序上一篇文章中,我们创建了数据库了




ORM框架_关联字段_抽象模型类_CRUD操作


    • CRUD的含义
      • 数据写入
      • 查询数据
      • 更新数据
      • 删除数据
      • 关联字段
      • 定义抽象模型类
      • 设置默认排序





上一篇文章中,我们创建了数据库了,那么在django中,如何将这些数据进行增删改查呢?

CRUD的含义

crud 是指在做计算处理时的增加(Create)、读取(Read)、更新(Update)和删除(Delete)几个单词的首字母简写。crud主要被用在描述软件系统中数据库或者持久层的基本操作功能。


数据写入

写入数据库共有两种方式
# 导入模型类
from project.models import Project
# 方式一
// 我们在视图中通过 Project 对象创建指定数据,然后再调用 save 方法进行保存
class ProjectsViews(View):
def get(self, request, pk):
obj = Project(name="金融项目", leader="余少琪")
# 保存数据 到 数据库
obj.save()


// 方式二
// 直接使用 Project.objects.create 方法创建数据,这种方式会直接往数据库写入数据
class ProjectsViews(View):
def get(self, request, pk):
# 直接存入数据库
Project.objects.create(name="xxx金融项目", leader="余少琪")

查询数据

查询多条数据

class ProjectsViews(View):
def get(self, request, pk):
# 查询所有数据
qs = Project.objects.all()

  1. 使用模型类的 Project.objects.all() ,会将当前模型类对应的数据表中所有数据都读取出来
  2. Project.objects.all() 返回的是 QuerySet对象(查询集对象)
  3. QuerySet 对象类似于列表,具有惰性查询的特征,(在“用”数据时,才会执行sql语句)

查询单条数据

方式一:

class ProjectsViews(View):
def get(self, request, pk):
# 通过id获取数据
obj = Project.objects.get(id=1)
pass

  1. 使用 Project.objects.get()
  2. 如果 get 查询的记录不存在,会抛出异常
  3. 如果 get 查询记录存在多条,如我们 Project.objects.get(name="ysq") ,数据库中查询出来多条数据,也会抛出异常
  4. 结合第三点,因此我们最好使用具有唯一约束的对象进行查询
  5. 如果使用指定条件查询的记录数据为1,会返回这条记录对应的模型实例对象,可以使用模型对象.字段名去获取相应的字段值

方式二:

class ProjectsViews(View):
def get(self, request, pk):
obj = Project.objects.filter(id=1)
pass

  1. 使用 Project.objects.filter() ,返回 QuerySet 对象
  2. 如果查询条件不存在,不会报错,会返回空的 QuerySet 对象
  3. 如果使用指定条件查询的记录数量超过1条,会将符合条件的模型对象包裹到 QuerySet 对象中返回
  4. 如果使用指定条件查询的记录为1条,会返回这条记录对应的模型实例对象,可以使用模型对象.字典名称去获取相应的字段值

tips:什么是 QuerySet 对象,它拥有哪些特性?

首先, QuerySet 类似于 python中的列表。


  1. 支持通过数值 (正整数)获取索引值
  2. 支持切片操作(正整数)
  3. 获取第一个模型对象:Project.objects.filter(name="yushaoqi").first()
  4. 获取最后一个模型对象:Project.objects.filter(name="yushaoqi").last()
  5. 获取长度: len(Project.objects.filter(name="yushaoqi"))Project.objects.filter(name="yushaoqi").count()
  6. 判断查询条件是否为空: Project.objects.filter(name="yushaoqi").exits()
  7. 支持迭代操作(for循环,每次循环返回模型对象)

更新数据

# 更新数据库表中的数据
class ProjectsViews(View):
def get(self, request, pk):

# 先获取到我们需要修改的数据
project_obj = Project.objects.get(id=1)
# 获取到之后,然后我们在直接赋值
project_obj.name = "猪猪框架"
project_obj.leader = '可爱的猪猪'

# 记得一定要调用 save() 方法才会保存数据
project_obj.save()

更新之后我们来查询一下数据,可以看到虽然我们数据更新了,但是此时他也自动更新了 update_time , 如果我们不想要更新 这个时间呢,应该怎么处理?

在这里插入图片描述
可以使用 save(update_fields=['xxx', 'xxx']) 方法,指定更新参数

class ProjectsViews(View):
def get(self, request, pk):
# 外键对应的父表如何传递
project_obj = Project.objects.get(id=1)
project_obj.name = "猪猪框架"
project_obj.leader = '可爱的猪猪'
project_obj.save(update_fields=['name', 'leader'])
pass

  1. 由此可见,我们可以查询数据之后,然后再将原先的数据赋值
  2. 一定要使用 save() 方法才能保存数据
  3. 通常直接调用 save(), 会更新时间,如果我们不想更新的话,可以使用 save(update_fields=['xxx', 'xxx']) 方法

更新多条数据

// 同时更新多条数据
class ProjectsViews(View):
def get(self, request, pk):
# 将所有名称中包含“项目”关键字的作者名称更改为 “珍惜”
Project.objects.filter(name__contains="项目").update(leader="珍惜")
pass

删除数据

删除单条数据

class ProjectsViews(View):
def get(self, request, pk):

# 获取到 id 为 1 的数据
project_obj = Project.objects.get(id=1)
# delete() 方法直接删除
project_obj.delete()
pass

  1. 删除单条数据,可使用 delete() 直接删除

删除多条数据

class ProjectsViews(View):
def get(self, request, pk):
# 将所有名称中包含“项目”关键字的作者名称更改为 “珍惜”
Project.objects.filter(name__contains="项目").delete()
pass

  1. 删除多条数据时,可以通过 filter 筛选出需要筛选出的数据,然后同样调用 delete() 方法进行删除

关联字段

什么是关联字段?

关联字段说白点,就是如果想将两个表的数据关联起来,就需要2个表各有1个字段将2个表关联起来,这个字段就是关联字段。

如果数据库中做过多表联查的小伙伴就不难理解,如需同时查询多张表时,那么不同表中的需要关联查询的字段,就是我们的关联字段。

假设我们现在有两张表

班级表:ID、班级名称
在这里插入图片描述

学生表:ID、学生名称、班级ID

在这里插入图片描述
假设我们需要查询某个班级中的所有学生,这个时候,我们应该怎么查询,是不是先需要从班级表中获取到该班级的所属ID,因此学生表中的 class_id,对应的是班级表中的ID,并且ID相同,这就是关联字段

那么我们了解了关联字段之后,结果之前所学习的场景,之前我们创建了项目表,现在我们要创建一个接口表,我们来实战一下。


  1. 我们需要创建一个命名为 interfaces的子应用,其中 interfaces 对应 project应用。

python manage.py startapp interface .

  1. 创建完成之后,我们需要在 setting.py 文件中的 INSTALLED_APPS 注册子应用

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'project',
# 在这里添加子应用的名称
"interfaces",
]

  1. 在子应用中,创建 model.py 模型类

class InterFaces(models.Model):
id = models.IntegerField(primary_key=True, verbose_name="id主键", help_text="id主键")
name = models.CharField(verbose_name="接口名称", help_text="接口名称", max_length=20, unique=True)
tester = models.CharField(verbose_name="测试人员", help_text="测试人员", max_length=20)
projects = models.ForeignKey('project.Project', on_delete=models.CASCADE, verbose_name="所属项目", help_text="所属项目")
create_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)

可以看到,我们接口表中的 projects 我们定义为外键字段,这里我们运用到了 ForeignKey

ForeignKey


  1. 使用 ForeignKey时,第一个参数作为必传参数,指定需要关联的父表模型类
    (1)第一个参数值可以直接使用父表模型类引用
    (2)或者可以使用 “子应用名称.父表模型类名称” 推荐这种写法
  2. ForeignKey 需要使用 on_delete 指定级联删除策略
    (1)CASCADE:当父表数据删除时,相对应的从表数据会被自动删除
    (2)SET_NULL:当父表数据删除时,相对应的从表数据会被自动设置为null值
    (3)SET_DEFAULT:当父表数据删除时,相对应的从表数据会被设置为默认值,还需要额外指定 defalut=True

定义抽象模型类

ok,到目前为止,我们一共定义了两个模型类,分别为 Project、InterFaces,他们都会设计到 创建时间、更新时间。那么当我们每个模型都需要这两个字段的时候,每个模型都写会有些冗余,因此我们可以封装一个工具类,将这一块抽离出来,单独封装一个公共模型类来继承它。

我们在主路径下方创建一个 util文件夹,并且创建 base_model.py文件

from django.db import models
class BaseModel(models.Model):
create_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
class Meta:
# 在内部类 Meta 中一旦指定了 abstract = True,那么当前模型类,为抽象模型类,在迁移时不会创建表,仅仅是为了供其他类继承
abstract = True

注意,通常我们定义模型类的时候,我们生成迁移文件的时候,会将该模型类也生成迁移文件,但是这个既然是公共模型类,显然我们是不需要生成数据库表的,因此我们可以在 内部类 Meta 中使用 abstract 参数,设置成 True。

abstract = True,那么当前模型类,为抽象模型类 ,在迁移时不会创建表,仅仅是为了供其他类继承

在这里插入图片描述
定义了公共类之后,我们继承 BaseModel 即可。


# 这里直接继承 BaseModel
class InterFaces(BaseModel):
id = models.IntegerField(primary_key=True, verbose_name="id主键", help_text="id主键")
name = models.CharField(verbose_name="接口名称", help_text="接口名称", max_length=20, unique=True)
tester = models.CharField(verbose_name="测试人员", help_text="测试人员", max_length=20)
# 如果需要创建一对多的外键,那么会在多的那一个模型类型中,定义外键字段
projects = models.ForeignKey('project.Project', on_delete=models.CASCADE, verbose_name="所属项目", help_text="所属项目")
create_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
class Meta:
# 自定义数据库名称
db_table = 'tb_interfaces'
verbose_name = "接口表"
verbose_name_plural = "接口表"

设置默认排序

我们可以在内部 Meta 类中定义 ordering,可以定义排序规则,默认我们设置成 ‘id’排序, 这里最好每个类都加上,否则会有一个告警信息。

class Meta:
# 自定义数据库名称
db_table = 'tb_interfaces'
verbose_name = "接口表"
verbose_name_plural = "接口表"
# 根据 ID 排序
ordering = ['id']






推荐阅读
  • Django框架下的对象关系映射(ORM)详解
    在Django框架中,对象关系映射(ORM)技术是解决面向对象编程与关系型数据库之间不兼容问题的关键工具。通过将数据库表结构映射到Python类,ORM使得开发者能够以面向对象的方式操作数据库,从而简化了数据访问和管理的复杂性。这种技术不仅提高了代码的可读性和可维护性,还增强了应用程序的灵活性和扩展性。 ... [详细]
  • voc生成xml 代码
    目录 lxmlwindows安装 读取示例 可视化 生成示例 上面是代码,下面有调用示例 api调用代码,其实只有几行:这个生成代码也很简 ... [详细]
  • 在 Windows 10 系统下配置 Python 3 和 OpenCV 3 的环境时,建议使用 Anaconda 分发版以简化安装过程。Anaconda 可以从其官方网站(https://www.anaconda.com/download)下载。此外,本文还推荐了几本关于 Python 和 OpenCV 的专业书籍,帮助读者深入理解和应用相关技术。 ... [详细]
  • 优化后的标题:数据网格视图(DataGridView)在应用程序中的高效应用与优化策略
    在应用程序中,数据网格视图(DataGridView)的高效应用与优化策略至关重要。本文探讨了多种优化方法,包括但不限于:1)通过合理的数据绑定提升性能;2)利用虚拟模式处理大量数据,减少内存占用;3)在格式化单元格内容时,推荐使用CellParsing事件,以确保数据的准确性和一致性。此外,还介绍了如何通过自定义列类型和优化渲染过程,进一步提升用户体验和系统响应速度。 ... [详细]
  • 通过优化模板消息机制,本研究提出了一种高效的信息化推送方案。该方案利用获取的访问令牌(access token)和指定的模板ID,实现了精准且快速的信息推送,显著提升了用户体验和信息传递效率。具体实现中,通过调用相关API接口,确保了消息的准确性和及时性,为用户提供更加便捷的服务。 ... [详细]
  • 深入解析 Django 中用户模型的自定义方法与技巧 ... [详细]
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • Python 数据分析领域不仅拥有高质量的开发环境,还提供了众多功能强大的第三方库。本文将介绍六个关键步骤,帮助读者掌握 Python 数据分析的核心技能,并深入探讨六款虽不广为人知但却极具潜力的数据处理库,如 Pandas 的替代品和新兴的可视化工具,助力数据科学家和分析师提升工作效率。 ... [详细]
  • Django项目中配置媒体文件路径的详细步骤与最佳实践
    在Django项目中配置媒体文件路径的详细步骤包括:首先,创建一个新的应用(如 `app02`),然后在 `settings.py` 文件中配置媒体文件的存储路径。具体来说,需要导入 `os` 模块,并使用 `os.path.join` 方法来指定媒体文件的保存目录。此外,建议在开发和生产环境中分别设置不同的媒体文件路径,以确保项目的灵活性和安全性。为了更好地管理和访问媒体文件,还可以在 `urls.py` 中添加相应的URL配置,以便在开发服务器上直接访问这些文件。 ... [详细]
  • 本文深入探讨了 iOS 开发中 `int`、`NSInteger`、`NSUInteger` 和 `NSNumber` 的应用与区别。首先,我们将详细介绍 `NSNumber` 类型,该类用于封装基本数据类型,如整数、浮点数等,使其能够在 Objective-C 的集合类中使用。通过分析这些类型的特性和应用场景,帮助开发者更好地理解和选择合适的数据类型,提高代码的健壮性和可维护性。苹果官方文档提供了更多详细信息,可供进一步参考。 ... [详细]
  • 计算 n 叉树中各节点子树的叶节点数量分析 ... [详细]
  • 在CentOS上部署和配置FreeSWITCH
    在CentOS系统上部署和配置FreeSWITCH的过程涉及多个步骤。本文详细介绍了从源代码安装FreeSWITCH的方法,包括必要的依赖项安装、编译和配置过程。此外,还提供了常见的配置选项和故障排除技巧,帮助用户顺利完成部署并确保系统的稳定运行。 ... [详细]
  • Python学习:环境配置与安装指南
    Python作为一种跨平台的编程语言,适用于Windows、Linux和macOS等多种操作系统。为了确保本地已成功安装Python,用户可以通过终端或命令行界面输入`python`或`python3`命令进行验证。此外,建议使用虚拟环境管理工具如`venv`或`conda`,以便更好地隔离不同项目依赖,提高开发效率。 ... [详细]
  • Python网络爬虫入门:利用urllib库进行数据抓取
    Python网络爬虫入门:利用urllib库进行数据抓取在数据科学和Web开发领域,Python凭借其简洁高效的特性成为首选语言。本文主要介绍了如何在Windows环境下使用Python的urllib库进行基本的网络数据抓取。考虑到命令行操作的不便,作者选择了Jupyter Notebook作为开发环境,不仅简化了配置过程,还提供了直观的数据处理和可视化功能。通过实例演示,读者可以轻松掌握urllib的基本用法,为深入学习网络爬虫技术打下坚实基础。 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
author-avatar
小程序员
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有