Django ORM 入门指南

Django ORM 让你用 Python 代码操作数据库。本文讲解模型定义、增删改查、高级查询技巧(Q/F/annotate)与性能优化(select_related/prefetch_related),一篇入门。

最佳实践
并发任务的多路径协同插画

直接回答:Django ORM 是框架内置的对象关系映射系统:用 Python 类定义数据模型,用链式查询代替手写 SQL,配合自动迁移与智能查询优化,是 Python 世界最成熟的 ORM 之一。

模型即表

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

class Book(models.Model):
    title = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="books")
    published = models.DateField()

makemigrations + migrate 两条命令完成建表——模型表达目标结构,迁移文件记录演进历史;部署前应审查迁移并检查数据库实际状态。

CRUD 四板斧

# 增
author = Author.objects.create(name="王小波", email="wxb@example.com")
book = Book.objects.create(title="沉默的大多数", price=39.0, author=author, published="1997-05-01")

# 查
Book.objects.get(id=1)                          # 单条,不存在抛 DoesNotExist
Book.objects.filter(price__lt=50)               # 价格小于 50
Book.objects.filter(title__icontains="沉默")     # 模糊搜索

# 改
book.price = 45.0
book.save()
# 或批量:Book.objects.filter(author=author).update(price=42)

# 删
book.delete()

字段查找的双下划线语法(__lt、__icontains、__year)是 Django ORM 的招牌表达力。

进阶查询

Q 对象——OR 与复杂逻辑:

from django.db.models import Q
Book.objects.filter(Q(price__lt=30) | Q(title__icontains="青铜"))

F 表达式——字段间比较与原子更新:

from django.db.models import F
Book.objects.filter(price__gt=F("author__books__price"))   # 字段比字段
Book.objects.update(price=F("price") * 1.1)                # 原子涨价,无竞态

聚合注解:

from django.db.models import Avg, Count
Author.objects.annotate(book_count=Count("books"), avg_price=Avg("books__price"))

性能优化:干掉 N+1

ORM 最大的性能杀手是 N+1 查询。两味解药:

# 多对一/一对一:JOIN 取关联对象
Book.objects.select_related("author")

# 反查/多对多:两次查询 + Python 拼接
Author.objects.prefetch_related("books")

再配 only()/defer() 控制取列、iterator() 流式处理大结果集、explain() 看查询计划,可进一步检查查询数量、执行计划及数据库负载。

常见问题(FAQ)

Q:Django ORM 和 SQLAlchemy 怎么选?
A:写 Django 项目就用内置 ORM——和迁移、Admin、表单深度联动;SQLAlchemy 表达力更强、独立于框架,适合非 Django 项目或复杂查询场景。

Q:什么时候该写原生 SQL?
A:先考虑 ORM 表达式、Window 和数据库函数;无法表达时再用参数化 raw()。extra() 是旧接口,不建议新代码优先采用。能用 ORM 就别手写——参数化防注入、迁移联动都是免费的。

Q:迁移冲突怎么解决?
A:多人并行改模型时常见。先检查迁移冲突,兼容分支可用 makemigrations --merge。共享环境已执行的迁移不要随意删除重写;结构冲突应编写后续迁移并备份验证。预防胜于治疗:模型改动勤沟通、小步提交。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台