Django ORM 详解:从入门到进阶,掌握数据库操作的核心

在 Django 中,ORM(Object Relational Mapping,对象关系映射) 是框架的核心之一。它允许你使用 Python 代码来操作数据库,而无需编写原始 SQL 语句。Django ORM 不仅简化了数据库操作,还提升了代码的可读性、可维护性和安全性。

本文将带你从基础到进阶,全面了解 Django ORM 的使用方式,包括模型定义、字段类型、查询操作、聚合函数、关系映射、性能优化等内容。


一、什么是 Django ORM?

ORM 是一种编程技术,它将数据库中的表映射为 Python 类,表中的行映射为类的实例,字段映射为类的属性。

在 Django 中:

  • 每个模型(Model)对应数据库中的一张表;
  • 每个模型实例对应表中的一条记录;
  • 每个模型类的属性对应表中的字段。

优点:

  • 跨数据库兼容:支持多种数据库(PostgreSQL、MySQL、SQLite、Oracle);
  • 避免 SQL 注入:ORM 会自动处理参数化查询;
  • 提高开发效率:用 Python 代码操作数据库,无需写 SQL;
  • 结构清晰:模型定义清晰,易于维护。

二、定义模型(Model)

示例:定义一个博客文章模型

from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)email = models.EmailField(unique=True)def __str__(self):return self.nameclass Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()author = models.ForeignKey(Author, on_delete=models.CASCADE)published = models.BooleanField(default=True)created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.title

常见字段类型:

字段类型

说明

CharField

字符串字段,必须指定 max_length

TextField

长文本字段

IntegerField

整数

BooleanField

布尔值(True/False)

DateTimeField

时间日期字段,auto_now_add

自动设置创建时间,auto_now

自动更新时间

EmailField

邮箱字段,自动验证格式

ForeignKey

外键,用于建立一对多关系

ManyToManyField

多对多关系

OneToOneField

一对一关系


三、字段选项(Field Options)

字段可以设置各种选项,控制其行为:

选项

说明

null=True

允许该字段为 NULL(数据库层面)

blank=True

表单验证时允许为空(Django 层面)

default=...

设置默认值

unique=True

字段值必须唯一

verbose_name='中文名'

字段的可读名称,用于管理界面

help_text='说明文字'

表单帮助信息

choices=...

限制字段的取值范围,如性别字段

示例:

GENDER_CHOICES = (('M', '男'),('F', '女'),
)class Profile(models.Model):gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

四、模型关系

Django ORM 支持三种主要的关系类型:

1. 一对一(OneToOneField)

class User(models.Model):username = models.CharField(max_length=100)class UserProfile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)bio = models.TextField()

2. 一对多(ForeignKey)

class Post(models.Model):author = models.ForeignKey(Author, on_delete=models.CASCADE)

3. 多对多(ManyToManyField)

class Tag(models.Model):name = models.CharField(max_length=30)class Post(models.Model):tags = models.ManyToManyField(Tag)

五、查询操作(QuerySet)

Django ORM 提供了强大的查询 API,可以使用链式调用构建复杂的查询。

1. 基本查询

Post.objects.all()                # 获取所有文章
Post.objects.get(id=1)            # 获取主键为 1 的文章(不存在会抛异常)
Post.objects.filter(title='Django') # 过滤标题为 Django 的文章
Post.objects.exclude(title='SQL')   # 排除标题为 SQL 的文章

2. 查询条件(Field Lookups)

条件

示例

说明

__exact

title__exact='Django'

精确匹配

__iexact

title__iexact='django'

忽略大小写匹配

__contains

title__contains='Python'

包含字符串

__icontains

title__icontains='python'

忽略大小写包含

__gt

price__gt=100

大于

__gte

price__gte=100

大于等于

__lt

price__lt=100

小于

__lte

price__lte=100

小于等于

__in

id__in=[1,2,3]

在某个列表中

__isnull

name__isnull=True

判断是否为 NULL

3. 排序与切片

Post.objects.order_by('title')            # 按标题升序
Post.objects.order_by('-title')           # 按标题降序
Post.objects.all()[:5]                    # 取前5条记录

4. 聚合查询(Aggregate)

from django.db.models import Count, Avg, Max, Min, SumPost.objects.aggregate(Avg('id'))         # 平均值
Post.objects.aggregate(Max('id'))         # 最大值
Post.objects.annotate(count=Count('author')) # 按作者统计文章数量

六、Meta 元类配置

通过 class Meta 可以配置模型的元信息:

class Post(models.Model):title = models.CharField(max_length=200)class Meta:db_table = 'blog_posts'             # 自定义表名ordering = ['-created_at']          # 默认排序verbose_name = '博客文章'verbose_name_plural = '博客文章列表'

七、模型方法

你可以在模型中定义自定义方法,用于封装业务逻辑:

class Person(models.Model):first_name = models.CharField(max_length=50)last_name = models.CharField(max_length=50)def full_name(self):return f"{self.first_name} {self.last_name}"

八、迁移(Migrations)

每次修改模型后,需要运行迁移命令更新数据库结构:

# 生成迁移文件
python manage.py makemigrations# 应用迁移
python manage.py migrate

九、性能优化技巧

1. 使用 select_related()(用于 ForeignKey)

Post.objects.select_related('author').all()

2. 使用 prefetch_related()(用于 ManyToManyField)

Post.objects.prefetch_related('tags').all()

3. 使用 only()defer()

Post.objects.only('title', 'author')  # 只加载部分字段
Post.objects.defer('content')         # 排除某些字段

4. 使用 exists() 判断是否存在

Post.objects.filter(title='Django').exists()

十、总结

Django ORM 是一个强大而灵活的数据库抽象层,它让开发者可以用 Python 代码操作数据库,极大提升了开发效率和代码可维护性。

本文我们讲解了:

  • ORM 的基本概念和优势
  • 如何定义模型、字段和关系
  • 查询操作(filter、exclude、order_by 等)
  • 聚合与统计
  • Meta 元类配置
  • 模型方法
  • 迁移命令
  • 性能优化技巧

掌握 Django ORM 是使用 Django 构建 Web 应用的关键技能。接下来你可以深入学习:

  • 自定义查询(Raw SQL、extra)
  • 数据库函数(如 Concat、Substr)
  • 使用事务(transaction)
  • 使用数据库索引优化查询性能

十一、参考资料

Models | Django documentation | Django

QuerySet API reference | Django documentation | Django

LearnDjango | LearnDjango.com

Page not found | LearnDjango.com

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

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

相关文章

mac中使用gvm install没有效果

问题表现: mac使用了gvm install一直没有效果(添加代理也没效果),效果如下图所示,始终卡在downloading,但是gvm version是正常的解决办法: 手动安装go的版本(版本号自行选择&#xf…

【React】状态管理

两个状态管理工具: dva 是一个基于 Redux 和 React Router 的数据流方案,它提供了对 Redux 和 React Router 的封装,使得在使用 dva 时可以更方便地进行状态管理和路由操作。React Redux是一个JavaScript状态管理库,它的核心包括s…

⭐CVPR2025 FreeUV:无真值 3D 人脸纹理重建框架

📄论文题目:FreeUV: Ground-Truth-Free Realistic Facial UV Texture Recovery via Cross-Assembly Inference Strategy ✍️作者及机构:Xingchao Yang、Takafumi Taketomi、Yuki Endo、Yoshihiro Kanamori(CyberAgent、Universit…

Google Chrome <140.0.7297.0 MediaStreamTrackImpl UAF漏洞

【高危】Google Chrome <140.0.7297.0 MediaStreamTrackImpl UAF漏洞 漏洞描述 Google Chrome 是美国谷歌&#xff08;Google&#xff09;公司的一款Web浏览器。 受影响版本中&#xff0c;当处理媒体流时&#xff0c;MediaStreamTrackImpl 组件在销毁前&#xff0c;未能清…

在VSCode中定制C语言宏格式化

在编写C语言代码时,经常会遇到一些宏定义的问题,特别是当使用宏来简化变量声明时。假设你有一个宏定义如下: #define VAR(vartype, memclass) vartype VAR(float32, AUTOMATIC) var1; // 等同于 "float32 var1;"当你使用VSCode的Format Document</

LangChain4J入门:使用SpringBoot-start

这是连续的专栏内容 &#xff08;一&#xff09;提换依赖 将原有的 <!-- LangChain4j OpenAI 集成 --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId></dependency> 换成 <!…

AR-Align-NN-2024

文章目录An unsupervised multi-view contrastive learning framework with attention-based reranking strategy for entity alignment摘要1. 引言2. 相关工作2.1. 实体对齐2.2 对比学习中的数据增强3. 问题定义4. 方法论4.1 嵌入初始化4.2 图谱数据增强4.3 多视图对比学习4.4…

DeFi借贷协议深度解析:原理与Python实现

目录 DeFi借贷协议深度解析:原理与Python实现 1. DeFi借贷协议概述 2. 核心数学原理 2.1 抵押率计算 2.2 健康因子 2.3 利率模型 3. 协议核心组件 3.1 资金池架构 3.2 状态变量 4. 核心功能实现 4.1 存款功能 4.2 借款功能 4.3 利息计算与更新 5. 清算机制实现 5.1 清算逻辑 5…

信创及一次ORACLE到OB的信创迁移

信创及一次ORACLE到OB的信创迁移 1.信创是什么? 2.银行信创要求:核心目标与挑战 3.一次ORACLE到OceanBase(OB)的信创迁移方案 3.0.目标: 3.1.迁移评估OceanBase Migration Assessment (OMA) 3.2.数据对象迁移 3.3.数据迁移 3.4.OceanBase 导数工具 3.5.调用存储过程跑批 3…

[Python] -进阶理解10- 用 Python 实现简易爬虫框架

网络爬虫是自动抓取网页并提取数据的程序。本篇文章将基于 Python,从请求、解析和数据流控制三个核心模块出发,逐步构建一个简易爬虫框架,并辅以代码示例与扩展建议,适合初学者快速掌握爬虫架构设计。 一、爬虫架构总览 典型爬虫框架包含以下模块流程: Seed URLs:初始化…

oracle备库主机断电重启后IO异常报错

两节点rac adg环境4个实例&#xff0c;节点1异常重启后IO报错 检查控制文件为0字节&#xff0c;第一感觉是不是控制文件损坏了&#xff1f;但节点2说是没有报错&#xff0c;理论上如果控制文件坏了&#xff0c;库应该挂掉了。 尝试重启另外一共adg实例&#xff0c;发现读取其它…

简单线性回归模型原理推导(最小二乘法)和案例解析

线性回归是一种用于建模自变量与因变量之间线性关系的统计方法&#xff0c;核心是通过最小化误差平方和估计模型参数。以下从数学原理推导和案例两方面详细说明。 一、线性回归模型的数学原理推导 1. 模型定义 线性回归假设因变量 y 与自变量 x 存在线性关系&#xff0c;具体…

主成分分析法 PCA 是什么

主成分分析法 PCA 是什么 主成分分析法(Principal Component Analysis,简称PCA)是一种数据降维与特征提取方法,核心思想是通过线性变换将高维数据映射到低维空间,在尽可能保留原始数据“信息量”(即方差)的同时,减少数据维度,消除特征间的相关性。 主成分分析法(PC…

Elasticsearch太重?试试轻量、极速的Meilisearch

在构建现代化的应用时&#xff0c;“搜索”早已不再是锦上添花的功能&#xff0c;而是决定用户留存体验的关键一环。Meilisearch&#xff0c;作为一款专为速度、易用性与开发者体验而生的开源搜索引擎&#xff0c;正受到越来越多开发者的青睐。 本文将介绍 Meilisearch 的核心…

车载通信架构 ---车内通信的汽车网络安全

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

MySQL: with as与with RECURSIVE如何混合使用?

文章目录一、with用法系列文章二、前言三、MySQL 普通CTE与递归CTE混合使用的严格规则四、解决方案4.1、方法1&#xff1a;嵌套查询4.2、方法2&#xff1a;使用临时表4.3、方法3&#xff1a;分开执行&#xff08;应用层处理&#xff09;本文主要探讨mysql中with普通cte与递归ct…

腕管综合征 : “鼠标手”| “数字时代工伤”,在我国视频终端工作者中患病率达12%到15%。“

文章目录 引言 I 预防“鼠标手” 肌腱的滑动 正中神经的滑动 II “鼠标手”是怎么发生的? 症状 “鼠标手”的高发人群 引言 “鼠标手”发展到晚期会对神经造成不可逆的损伤。 早期刚开始有症状,比如说轻微的麻木,持续的时间也不长,发作频率也不高的情况下,我们可以通过像…

#C语言——刷题攻略:牛客编程入门训练(三):输出格式化、基本运算符

&#x1f31f;菜鸟主页&#xff1a;晨非辰的主页 &#x1f440;学习专栏&#xff1a;《C语言刷题合集》 &#x1f4aa;学习阶段&#xff1a;C语言方向初学者 ⏳名言欣赏&#xff1a;"代码行数决定你的下限&#xff0c;算法思维决定你的上限。" 目录 1. 牛牛的空格分…

【ELasticsearch】集群故障模拟方案(二):磁盘空间满、重选主节点

《集群故障模拟方案》系列&#xff0c;共包含以下文章&#xff1a; 1️⃣ 集群故障模拟方案&#xff08;一&#xff09;&#xff1a;节点宕机、节点离线2️⃣ 集群故障模拟方案&#xff08;二&#xff09;&#xff1a;磁盘空间满、重选主节点 &#x1f60a; 如果您觉得这篇文章…

React中的Hooks

在React 16.8版本之前&#xff0c;组件主要分为两种&#xff1a;类组件&#xff08;Class Components&#xff09; 和 函数组件&#xff08;Function Components&#xff09;。类组件可以使用 state 来管理内部状态&#xff0c;也能使用生命周期方法&#xff08;如 componentDi…