Django框架之ORM操作

news2024/11/24 14:04:51

一、选择数据库

1、默认数据库

  • Django默认的数据库是sqlite3数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

2、指定数据库

  • 修改连接到MySQL数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        # 数据库名字
        'NAME': "user_data",
        # 数据库用户名
        "USER": "root",
        # 数据库密码
        "PASSWORD": "111111",
        # 数据库 IP,本地默认是127.0.0.1/localhost
        "HOST": "127.0.0.1",
        # 数据库端口
        "PORT": 3306,
        # 数据库编码
        "CHARSET": "utf8mb4",
    }
}

3、指定MySQL数据库报错

django 默认使用mysqldb模块链接mysql,但是该模块的兼容性不好,需要手动修改为pymysql链接

(1)解决办法一:猴子补丁

  • 在项目下的 __init__ 或者任意的应用名下的 __init__ 文件中书写一下代码
import pymysql

pymysql.install_as_MySQLdb()

(2)解决办法二:下载第三方模块

  • 直接安装
pip install mysqlclient
  • 运气好不会报错,但是运气不好就会报错
    • 报错的话下载whl文件
    • https://pypi.org/project/mysqlclient/#files
    • 下载对应的whl版本文件并安装
pip install pip mysqlclient-2.2.4-cp310-cp310-win_amd64.whl

二、连接数据库

  • 首先如下图,点击Database

在这里插入图片描述

  • 第二步,如下图

在这里插入图片描述

  • 第三步,填写相关信息

在这里插入图片描述

  • 第四步,不要着急确定,先点击Test Connection,看看是否能够连接成功

在这里插入图片描述

  • 最后,点击OK连接数据库成功

三、ORM介绍

1、什么是ORM

ORM(Object-Relational Mapping)是一种编程技术,用于在关系型数据库和面向对象编程语言之间建立映射关系,从而实现数据的持久化和操作。ORM工具可以将数据库中的表和记录映射到编程语言中的对象和属性,使开发人员可以使用面向对象的方式来操作数据库,而无需直接编写SQL语句。

简单来说,就是

  • 数据库中的表映射为Python中的类
  • 数据库中的字段映射为Python中的属性
  • 数据库中的记录映射为Python中的实例

2、使用Django ORM的好处

Django ORM(Object-Relational Mapping)是Django框架内置的ORM工具,用于简化与数据库的交互和操作。以下是使用Django ORM的一些优点:

  1. 简单易用:Django ORM提供了简单易用的API,使开发人员能够使用Python对象来表示数据库表和记录,从而减少了编写SQL语句的需要。

  2. 自动化数据库表创建:通过定义Django模型类,Django ORM可以自动创建对应的数据库表结构,无需手动编写SQL语句创建表。

  3. 数据关系管理:Django ORM支持定义数据之间的关系,如一对多、多对多等关系,开发人员可以轻松地处理复杂的数据关系。

  4. 查询表达式:Django ORM提供了丰富的查询表达式和方法,使开发人员能够轻松地执行各种复杂的数据库查询操作,如过滤、排序、分组等。

  5. 事务支持:Django ORM提供了事务管理的功能,确保数据库操作的原子性和一致性,避免数据不一致的情况发生。

  6. 性能优化:Django ORM提供了查询优化的功能,可以通过使用索引、延迟加载等技术来提高查询性能。

  7. 跨数据库支持:Django ORM支持多种数据库后端,开发人员可以在不同的数据库系统之间切换而无需修改大部分代码。

  8. 安全性:Django ORM可以防止SQL注入攻击,因为它会自动转义用户输入的数据,从而提高应用程序的安全性。

  9. 可扩展性:Django ORM支持自定义查询集、管理器和查询表达式,开发人员可以根据需要扩展其功能。

总的来说,Django ORM简化了与数据库的交互,提高了开发效率,同时提供了丰富的功能和性能优化选项,使开发人员能够更轻松地构建功能强大的Web应用程序。

四、ORM操作之建表

1、定义模型表

  • 应用下面的models.py文件
  • 数据库中的表映射为Python中的类
class User(models.Model):
    """
    数据库中的字段映射为Python中的属性
    定义一个用户名 : 字符串类型 长度
    MySQL中字符串类型的字段 : char varchar(32)
    CharField :字符串类型的字段
    max_length :最大长度
    verbose_name : 注释
    help_text : 解释
    """
    # username varchar(32)
    username = models.CharField(max_length=32, verbose_name="用户名", help_text="这是一个用户名字段")
    password = models.CharField(max_length=32)
    # IntegerField : 相当于MySQL中的 int 字段
    age = models.IntegerField()
    # FloatField : 相当于MySQL数据库中的 float 字段
    salary = models.FloatField()

2、数据库迁移

(1)命令行输入,生成迁移文件

python manage.py makemigrations

(2)迁移记录生效,同步到数据库中

python manage.py migrate

(3)注意事项

只要你修改了models.py中跟数据库中相关的代码,就必须重新执行上述的两条命令。

由于一张表中必须要有一个主键字段,并且一般情况下都叫id字段,所以ORM在当你不定义主键字段的时候,ORM会自动帮你创建一个名为id的主键字段,但是如果需要额外的叫法例如uid,aid等等,那么就需要自己手动去创建了

(4)补充

  • pycharm帮助我们偷懒的办法,直接点击下方按钮

在这里插入图片描述

  • 然后直接输入makemigrations和migrate即可

在这里插入图片描述

  • 最后我们在Database上就能看见各种表了

在这里插入图片描述

五、ORM操作之字段操作

1、字段的增加

要在 Django 模型表中增加新的字段,只需在相应的 Model 类中添加新字段及其类型和所需属性。

(1) 可以在终端内直接给出默认值

(2) 设置该字段可以为空
info = models.CharField(max_length=32,verbose_name='个人简介',null=True)

(3) 直接给字段设置默认值
hobby = models.CharField(max_length=32,verbose_name='兴趣爱好',default='study')  

2、 字段的修改

直接修改代码然后执行数据库迁移的两条命令即可

python manage.py makemigrations
python manage.py migrate

3、字段的删除

直接注释对应的字段然后执行数据库迁移的两条命令即可,但是执行完之后字段对应的数据也都没有了

所以在操作models.py的时候一定要注意:
千万不要轻易的注释一些字段,执行迁移命令之前最好先检查一下自己写的代码

六、ORM操作之数据操作

1、数据增加

(1)方式一

res = models.User.objects.create(username="张三",password=123456)
# res 就是当前被创建的对象本身

(2)方式二

user_obj = models.User(username=username,password=password)
user_obj.save()  # 保存数据

2、数据查询

(1)获取全部数据的方式

模型表名.objects.all()

(2)获取特定数据的方式

filter括号内可以携带多个参数,参数与参数之间默认是and关系,可以把filter联想成where记忆

# 方式一
模型表名.objects.get(筛选字段名=筛选字段值)

# 方式二
res = models.User.objects.filter(username="张三")
print(res)  #  # <QuerySet [<User: User object (1)>]>  [数据对象1,数据对象2,...]
user_obj = res[0]

"""
返回值可以先看成事列表套数据对象的格式。
它支持索引取值,切片操作,但是不支持负数索引;但是它不推荐你使用索引的方式取值
user_obj = models.User.objects.filter(username=username).first()
"""

(3)去除指定条件后的数据

模型表名.objects.exclude(筛选字段名=筛选字段值)

(4)示例

# 获取表中所有数据
all_records = MyModel.objects.all()

# 根据特定条件筛选数据(方式一)
filtered_records = MyModel.objects.get(name="张三")

# 根据特定条件筛选数据(方式二)
# 查询包含"张"的所有name
filtered_records = MyModel.objects.filter(name__contains="张")  

# 去除满足指定条件的数据
# 过滤掉所有年龄小于18岁的记录
excluded_records = MyModel.objects.exclude(age__lt=18) 

(5)补充

.filter()  过滤-->Queryset对象   
.first() .last()-->获取用户对象
.get()  直接拿到的就是用户对象

3、数据修改

(1)先查询直接修改

  • 推荐使用
模型表名.objects.filter(筛选字段名=筛选字段值).update(修改字段名=修改字段值)

(2)先查询后,再修改,最后保存

obj = 模型表名.objects.get(筛选字段名=筛选字段值)
obj.修改字段名=修改字段值
obj.save()

(3)示例

# 点击编辑按钮朝后端发送编辑数据的请求
    """
    如何告诉后端用户想要编辑哪条数据?
      将编辑按钮所在的哪一行数据的主键值发送给后端
      利用url问号后面携带参数的方式
    """
def edit_user(request):
    # 获取url后面的参数
    edit_id = request.GET.get('user_id')
    # 查询当前用户想要编辑的数据对象
    edit_obj = models.User.objects.filter(id=edit_id).first()
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 去数据库中修改对应的数据内容
        
        # 修改方式1
        models.User.objects.filter(id=edit_id).update(username=username,password=password)
        """
        将filter查询出来的列表中所有的对象全部更新  批量更新操作
        只修改被修改的字段,推荐使用
        """

        # 修改方式2
        edit_obj.username = username
        edit_obj.password = password
        edit_obj.save()
        """
        上述方法当字段特别多的时候效率会非常的低
        因为它是从头到尾将数据的所有字段全部更新一遍,无论该字段是否被修改
        """
        # 跳转到数据的展示页面
        return redirect('/user_list/')

    # 将数据对象展示到页面上
    return render(request,"05 edit_user.html",locals())

4、数据删除

(1)先查询直接删除

模型表名.objects.filter(筛选字段名=筛选字段值).delete()

(2)先查询再删除

instance_to_delete = MyModel.objects.get(筛选字段名=筛选字段值)
instance_to_delete.delete()

(3)示例

# 删除满足特定条件的记录,通常先通过查询获取对象实例再调用 .delete() 方法
instance_to_delete = MyModel.objects.get(name="张三")
instance_to_delete.delete()

# 可以使用 .filter() 方法批量删除
MyModel.objects.filter(name="李四").delete()  # 删除所有名字为"李四"的记录

(4)了解

删除数据内部其实并不是真正的删除,我们会给数据添加一个标识字段用来表示当前数据是否被删除了,如果数据被删了仅仅只是将字段修改了一个状态

七、Django ORM中如何创建表关系

1、表与表之间的关系

  • 一对多

  • 多对多

  • 一对一

判断表关系的方法:换位思考

2、创建表关系

  • 思路:先将基表创建出来,然后再添加外键字段
  • 思考:ORM中如何定义三种关系?
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) 
authors = models.ManyToManyField(to='Author')
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)

其中ForeignKey、OneToOneField会自动在字段后面加_id后缀,还需要手动加上 on_delete=models.CASCADE 来标识级联更新和删除(Django1.x版本不需要手动添加)

from django.db import models


class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    # 总共8位,小数点后面占2位
    """
    图书和出版社是一对多,并且书是多的一方,所以外键字段放在书表里面
    """
    publish = models.ForeignKey(to='Publish')  # to_field不写默认就是与出版社表的主键字段做外键关联
    """
    如果字段对应的是ForeignKey,那么ORM会自动在字段的后面加_id
    如果你自己加了_id,那么ORM还是会在后面继续加_id
    因此后面在定义ForeignKey的时候就不要自己加_id
    """

    """
    图书和作者是多对多的关系,外键字段建在任意一方均可,但是推荐你建在查询频率较高的一方
    """
    authors = models.ManyToManyField(to='Author')
    """
    authors是一个虚拟字段,主要是用来告诉ORM,书籍表和作者表是多对多关系
    让ORM自动帮你创建第三张关系表
    """


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    """
    作者与作者详情是一对一的关系,外键字段建在任意一方均可,但是推荐你建在查询频率较高的一方
    """
    author_detail = models.OneToOneField(to='AuthorDetail')
    """
    OneToOneField也会自动给字段加_id后缀
    """

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()  # 或者直接用字符类型
    addr = models.CharField(max_length=32)

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

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

相关文章

鸿蒙OpenHarmony【标准系统 烧录】(基于RK3568开发板)

烧录 烧录是指将编译后的程序文件下载到芯片开发板上的动作&#xff0c;为后续的程序调试提供基础。DevEco Device Tool提供一键烧录功能&#xff0c;操作简单&#xff0c;能快捷、高效的完成程序烧录&#xff0c;提升烧录的效率。 RK3568的镜像烧录通过Windows环境进行烧录&…

Oracle-OCR掉盘无法启动集群问题

问题背景&#xff1a; 用户在对一套Oracle11.2.0.4的RAC集群进行OCR掉盘测试&#xff0c;验证NORMAL冗余的OCR磁盘组的可用性。测试通过将udev配置里面的一块OCR盘注释&#xff0c;然后重启服务器集群模拟OCR磁盘组出现掉盘的情况。用户在测试中&#xff0c;注释掉udev配置里面…

嵌入式开发_DMA详解

在嵌入式开发的广阔天地中&#xff0c;MCU是众多开发者手中的利器。而DMA&#xff08;Direct Memory Access&#xff0c;直接内存访问&#xff09;技术&#xff0c;则如同一位高效的快递小哥&#xff0c;穿梭于处理器与外设之间&#xff0c;无需CPU亲自出马&#xff0c;高效地搬…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-8.1

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

【工具】--- Adobe Illustrator 下载-入门绘图

文章目录 软件下载入门项目可看课程 尝试使用Adobe Illustrator&#xff08;设计师常用软件&#xff09;进行科研绘图。 软件下载 阿里云盘下载 入门项目 绘制一个箭头并保持为SVG&#xff0c; 直线->画线->窗口->描边->选择想要的箭头样式->颜色->改为蓝…

众筹商城源码 众筹商品平台 商城加共识元富之路 网上商城众筹

众筹商城源码 众筹商品平台 商城加共识元富之路 网上商城众筹 前端是编译后的&#xff0c;后端PHP&#xff0c;带商城 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89161734 更多资源下载&#xff1a;关注我。

mybatis工程需要的pom.xml,以及@Data 、@BeforeEach、@AfterEach 的使用,简化mybatis

对 “mybatis - XxxMapper.java接口中方法的参数 和 返回值类型&#xff0c;怎样在 XxxMapper.xml 中配置的问题” 这篇文章做一下优化 这个pom.xml文件&#xff0c;就是上面说的这篇文章的父工程的pom.xml&#xff0c;即&#xff1a;下面这个pom.xml 是可以拿来就用的 <?…

Node.js 版本升级方法

在构建vue项目时&#xff0c;依赖npm&#xff08;Node Package Manager&#xff09;工具&#xff0c;类似于Java项目需要maven管理。而npm是node.js的管理工具&#xff0c;npm依赖node.js环境才能执行。 有时候使用voscode或者其他工具安装vue项目依赖&#xff0c;显示一直处于…

【自然语言处理】Word2VecTranE的实现

作业一 Word2Vec&TranE的实现 1 任务目标 1.1 案例简介 Word2Vec是词嵌入的经典模型&#xff0c;它通过词之间的上下文信息来建模词的相似度。TransE是知识表示学习领域的经典模型&#xff0c;它借鉴了Word2Vec的思路&#xff0c;用“头实体关系尾实体”这一简单的训练目…

【Vue3】Ref与Reactive

3.1【ref 创建&#xff1a;基本类型的响应式数据】 作用&#xff1a;定义响应式变量。语法&#xff1a;let xxx ref(初始值)。返回值&#xff1a;一个RefImpl的实例对象&#xff0c;简称ref对象或ref&#xff0c;ref对象的value属性是响应式的。注意点&#xff1a; JS中操作数…

【在线名字作画HTML源码】

在线名字作画HTML源码 效果图部分源码领取源码下期更新预报 效果图 部分源码 index.htm <!DOCTYPE html> <html> <head> <title>在线名字作画|民间花鸟字|多彩花鸟虫鱼组合书法|藏字画|字谜语|飞帛板书|意匠文字</title> <meta http-equiv&…

Profinet转Modbus网关接称重设备与1200PLC通讯

Profinet转Modbus网关&#xff08;XD-MDPN100&#xff09;是一种能够实现Modbus协议和Profinet协议之间转换的设备。Profinet转Modbus网关可提供单个或多个RS485接口&#xff0c;使用Profinet转Modbus网关将称重设备与西门子1200 PLC进行通讯&#xff0c;可以避免繁琐的编程和配…

【C++】深入了解C++内存管理

个人主页&#xff1a;救赎小恶魔 欢迎大家来到小恶魔频道 好久不见&#xff0c;甚是想念 今天我们要深入讲述类与对象的初始化列表以及隐式类型转换 目录 1.C的内存分布 2.C/C言中动态内存管理方式 1.C语言的管理方式 2.C的管理方式 new delete 3.operator new与ope…

如何删除BigKey

1.2.3、如何删除BigKey BigKey内存占用较多&#xff0c;即便时删除这样的key也需要耗费很长时间&#xff0c;导致Redis主线程阻塞&#xff0c;引发一系列问题。 redis 3.0 及以下版本 如果是集合类型&#xff0c;则遍历BigKey的元素&#xff0c;先逐个删除子元素&#xff0c;…

为什么选择OpenNJet?OpenNJet下一代云原生应用引擎!OpenNJet开发实战!

前言导读 在当今这个数字化转型加速的时代&#xff0c;云原生技术已成为企业和开发者构建现代应用的首选路径。OpenNJet作为新一代云原生应用引擎&#xff0c;在国内外技术社区受到了广泛关注。 本文将深入探讨OpenNJet的特点、优势以及在开发实践中的应用&#xff0c;带您全…

深度学习基础之《TensorFlow框架(16)—神经网络案例》

一、mnist手写数字识别 1、数据集介绍 mnist数据集是一个经典的数据集&#xff0c;其中包括70000个样本&#xff0c;包括60000个训练样本和10000个测试样本 2、下载地址&#xff1a;http://yann.lecun.com/exdb/mnist/ 3、文件说明 train-images-idx3-ubyte.gz: training s…

vscode 配置与插件记录

vscode插件 python PythonPython DebuggerruffisortPylanceJupyterJupyter KeymapJupyter Slide ShowJupyter Cell TagsautoDocstring - Python Docstring Generator ruff isort pylance autodocsting 在setting.json里这么配置&#xff0c;这样你保存时就会自动format…

【酱浦菌-爬虫项目】爬取学术堂论文信息

1. 首先&#xff0c;代码定义了一个名为 url 的变量&#xff0c;它是一个包含三个网址的集合&#xff08;或者说是一个集合的字典&#xff09;。这些网址分别是&#xff1a; - ‘http://www.xueshut.com/lwtimu/127966.html’ - ‘http://www.xueshut.com/lwtimu/12…

您可知道如何通过`HTTP2`实现TCP的内网穿透???

可能有人很疑惑应用层 转发传输层&#xff1f;&#xff0c;为什么会有这样的需求啊&#xff1f;&#xff1f;&#xff1f;哈哈技术无所不用其极&#xff0c;由于一些场景下&#xff0c;对于一个服务器存在某一个内部网站中&#xff0c;但是对于这个服务器它没有访问外网的权限&…

《ElementPlus 与 ElementUI 差异集合》el-dialog 显示属性有差异

ElementPlus 用属性 v-model ElementUI 用属性 visible 其实也是 Vue2/Vue3 的差异&#xff1a;v-model 指令在组件上的使用已经被重新设计&#xff0c;替换掉了 v-bind.sync