2.1 Django ORM 基础


文档摘要

第二章:模型(Models)与数据库 2.1 Django ORM 基础 Django ORM(Object-Relational Mapper,对象关系映射器)是 Django 框架的核心组件,为开发者提供了一套以 Python 对象方式操作关系型数据库的抽象层。它屏蔽了底层 SQL 差异,将数据库表映射为 Python 类、表记录映射为类实例、SQL 操作转换为方法调用,显著降低数据库交互复杂度,提升开发效率、代码可维护性与跨数据库可移植性。 本节系统讲解 Django ORM 的核心机制:从 ORM 设计理念出发,深入模型定义规范、字段类型与选项语义、迁移工作流原理,到 CRUD 操作实践、QuerySet 查询逻辑及链式调用范式,构建扎实的数据库操作能力基础。 2.1.

第二章:模型(Models)与数据库

2.1 Django ORM 基础

Django ORM(Object-Relational Mapper,对象关系映射器)是 Django 框架的核心组件,为开发者提供了一套以 Python 对象方式操作关系型数据库的抽象层。它屏蔽了底层 SQL 差异,将数据库表映射为 Python 类、表记录映射为类实例、SQL 操作转换为方法调用,显著降低数据库交互复杂度,提升开发效率、代码可维护性与跨数据库可移植性。

本节系统讲解 Django ORM 的核心机制:从 ORM 设计理念出发,深入模型定义规范、字段类型与选项语义、迁移工作流原理,到 CRUD 操作实践、QuerySet 查询逻辑及链式调用范式,构建扎实的数据库操作能力基础。

2.1.1 什么是 ORM?

传统 Web 开发中,直接编写 SQL 语句操作数据库存在多重挑战:

  • 学习与维护成本高:需掌握不同数据库方言(如 MySQL、PostgreSQL 的语法差异),复杂查询逻辑易出错且难以调试;
  • 代码重复性强:增删改查操作模板化,大量胶水代码削弱业务表达力;
  • 数据库强耦合:SQL 语句深度绑定特定数据库引擎,迁移至新数据库时需全面重写;
  • 安全风险突出:字符串拼接 SQL 易引发 SQL 注入漏洞,需额外投入防御性编码。

ORM 通过建立“类→表、实例→行、方法→操作”的三层映射,将数据操作转化为面向对象范式。其核心价值在于:

  • 声明式数据建模:用 Python 类定义结构,语义清晰、逻辑内聚;
  • 统一查询接口filter()exclude()get() 等方法屏蔽 SQL 细节;
  • 跨数据库兼容:同一套模型与查询逻辑可适配 SQLite、MySQL、PostgreSQL 等后端;
  • 内置安全防护:参数化查询机制天然防御 SQL 注入;
  • 开发体验优化:Django Admin、Shell 交互、迁移管理等工具链深度集成。

在 Django 中,ORM 由 django.db.models 模块实现,其能力通过模型(Model)定义与 QuerySet 查询接口共同承载。

2.1.2 Django 模型(Models)

模型是 Django ORM 的基石,本质为继承 models.Model 的 Python 类,每个类对应数据库中一张表,每个属性对应一个字段。模型不仅定义数据结构,还承载验证规则、关系声明与业务逻辑。

定义模型示例

# myapp/models.py from django.db import models from datetime import date class Book(models.Model): title = models.CharField(max_length=200, verbose_name="书名") author = models.CharField(max_length=100, verbose_name="作者") publication_date = models.DateField(verbose_name="出版日期") price = models.DecimalField( max_digits=5, decimal_places=2, verbose_name="定价", help_text="单位:人民币元" ) is_published = models.BooleanField( default=False, verbose_name="是否已出版" ) class Meta: verbose_name = "书籍" verbose_name_plural = "书籍" ordering = ["-publication_date"] def __str__(self): return self.title

关键要素解析

组成部分 说明
字段类型 CharFieldDateFieldDecimalField 等定义数据类型与约束;max_lengthmax_digits 等参数声明存储规格。
字段选项 verbose_name 提升管理后台可读性;help_text 提供表单提示;default 设置默认值;null(数据库允许 NULL)、blank(表单允许空)分离数据层与表现层约束。
Meta 类 声明模型元信息:verbose_name/verbose_name_plural 控制后台显示名称;ordering 定义默认排序;db_table 可自定义表名。
__str__ 方法 返回对象字符串表示,用于 Django Admin、Shell 及调试输出,提升可读性。

常用模型字段类型

字段类型 适用场景 典型参数
AutoField 主键(默认 id 字段) primary_key=True
CharField 短文本(标题、姓名) max_length=200
TextField 长文本(正文、描述)
IntegerField / FloatField 数值型数据
DecimalField 精确数值(价格、金额) max_digits=5, decimal_places=2
DateField / DateTimeField 时间信息 auto_now_add=True(创建时自动填充)
BooleanField 是/否状态 default=False
EmailField / URLField 格式化文本 自动验证邮箱/URL 格式
ForeignKey 一对多关系(如:图书←作者) on_delete=models.CASCADE
ManyToManyField 多对多关系(如:图书↔标签) related_name="books"
OneToOneField 一对一关系(如:用户↔个人资料) on_delete=models.PROTECT

模型激活流程:迁移(Migrations)

模型定义需通过迁移同步至数据库,流程严格遵循以下三步:

  1. 注册应用:在 settings.pyINSTALLED_APPS 中添加应用名(如 'myapp');
  2. 生成迁移文件:执行 python manage.py makemigrations,Django 检测模型变更并生成 .py 迁移脚本(如 0001_initial.py);
  3. 应用迁移:执行 python manage.py migrate,Django 执行迁移脚本,在数据库中创建/修改表结构。

关键提示:迁移文件是数据库演进的版本记录,必须提交至代码仓库。生产环境严禁直接修改数据库结构,所有变更均需通过迁移管理。

2.1.3 ORM 基本操作:CRUD

Django ORM 将数据库操作封装为直观的 Python 方法,核心围绕 Model.objects 管理器(Manager)展开,支持完整的 Create、Read、Update、Delete 操作。

创建(Create)

通过实例化模型类并调用 save() 方法插入数据:

from myapp.models import Book from datetime import date book = Book( title="Python 编程从入门到实践", author="Eric Matthes", publication_date=date(2019, 5, 1), price=59.90, is_published=True ) book.save() # 执行 INSERT,自动生成主键 ID print(f"书籍 '{book.title}' 已创建,ID:{book.id}")

读取(Read):QuerySet 查询

QuerySet 是惰性求值的对象集合,是 Django 查询的核心载体。常见操作:

  • 获取全部记录

    all_books = Book.objects.all() # 返回 QuerySet,未执行查询 print(f"共 {all_books.count()} 本书") # count() 触发 SELECT COUNT for book in all_books: # 迭代触发 SELECT print(f"- {book.title}({book.author})")
  • 条件过滤

    # 标题含 "Python" 且价格 ≥ 60 的书籍 expensive_python_books = Book.objects.filter( title__contains="Python", price__gte=60 ).order_by("-price") # 2020 年后出版的书籍 recent_books = Book.objects.filter( publication_date__year__gt=2020 )
  • 字段查找(Field Lookups)

    查找符 含义 示例
    __exact 精确匹配(默认) title__exact="Django"
    __iexact 忽略大小写匹配 title__iexact="django"
    __contains 包含子串 title__contains="Web"
    __icontains 忽略大小写包含 title__icontains="web"
    __startswith / __endswith 开头/结尾匹配 author__startswith="Eric"
    __gt / __gte / __lt / __lte 数值比较 price__gte=50
    __in 值在列表中 author__in=["Eric", "Robert"]
    __isnull 判断 NULL publication_date__isnull=True
    __range 闭区间范围 publication_date__range=(d1, d2)
  • 获取单个对象

    try: book = Book.objects.get(id=1) # 必须唯一,否则抛异常 print(f"ID=1 的书籍:{book.title}") except Book.DoesNotExist: print("未找到该书籍") except Book.MultipleObjectsReturned: print("查询返回多条记录")
  • 排除条件

    non_python_books = Book.objects.exclude(title__contains="Python")

更新(Update)

  • 单对象更新:获取实例 → 修改属性 → save()

    try: book = Book.objects.get(title="Python 编程从入门到实践") book.price = 69.90 book.is_published = False book.save() # 生成 UPDATE 语句 except Book.DoesNotExist: pass
  • 批量更新:直接操作 QuerySet,性能更优

    updated = Book.objects.filter(author="Eric Matthes").update( is_published=False ) print(f"更新 {updated} 条记录")

删除(Delete)

  • 单对象删除

    try: book = Book.objects.get(title="Python 编程从入门到实践") title = book.title book.delete() # 生成 DELETE 语句 print(f"已删除:{title}") except Book.DoesNotExist: pass
  • 批量删除

    deleted, details = Book.objects.filter(price__gt=100).delete() print(f"删除 {deleted} 条记录")

2.1.4 QuerySet 链式调用

QuerySet 支持方法链式调用,每个方法返回新 QuerySet,不修改原对象,支持组合复杂查询:

# 链式构建:Python 相关 + 价格 ≥ 60 + 按价格降序 + 仅取前 5 条 top_expensive_python = Book.objects \ .filter(title__icontains="python") \ .filter(price__gte=60) \ .order_by("-price") \ .values("title", "price", "publication_date") \ .distinct()[:5] for book in top_expensive_python: print(f"{book['title']} - ¥{book['price']}")

链式调用核心特性

  • 惰性求值(Lazy Evaluation):仅在访问数据(迭代、list()count())时执行 SQL,避免无谓查询;
  • 不可变性(Immutability):每次调用 filter()exclude() 等均返回新 QuerySet,原 QuerySet 不变;
  • 可组合性(Composability):支持任意顺序组合,如 filter().exclude().order_by()
  • 缓存优化:QuerySet 执行后结果缓存,重复访问不触发新查询。

2.1.5 本节总结

Django ORM 以模型为核心、QuerySet 为查询载体,构建了一套高效、安全、可维护的数据库操作范式。本节重点涵盖:

  • ORM 设计哲学:通过对象抽象解耦业务逻辑与数据库细节,提升工程化水平;
  • 模型定义规范:字段类型、选项语义、Meta 配置及迁移工作流,确保数据结构严谨可演进;
  • CRUD 实践要点save()/delete() 作用于实例,update()/delete() 作用于 QuerySet,理解适用场景;
  • QuerySet 惰性机制:链式调用构建灵活查询,延迟执行保障性能;
  • 字段查找体系__ 双下划线语法提供强大条件表达能力,覆盖 90%+ 查询需求。

掌握上述内容,即具备使用 Django 构建健壮数据层的基础能力。后续章节将深入模型关系建模(ForeignKey/ManyToManyField)、聚合统计(aggregate()/annotate())、性能优化(select_related()/prefetch_related())及高级查询技巧,持续深化 ORM 应用深度。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U