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。共享环境已执行的迁移不要随意删除重写;结构冲突应编写后续迁移并备份验证。预防胜于治疗:模型改动勤沟通、小步提交。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。