django Model模型层详解
作为django框架的「大脑中枢接口」,Model层是连接业务逻辑Python代码和relational-database数据的桥梁。今天我们就用清晰的实操路线,把django ORM和Model的核心知识点啃下来~
课程目标
- 理解django ORM的定位、价值
- 掌握Model的基础定义语法、字段类型
- 熟练操作数据库迁移(从创建表到维护表结构)
- 学会用QuerySet完成CRUD和常用查询
django ORM简介
ORM(Object-Relational Mapping,对象关系映射)不是django独有的,但却是django生态中「最具开发效率」的模块之一:
- 它把数据库表映射成Python类(我们写的Model)
- 把表中的一条记录映射成类的一个实例
- 把SQL的增删改查、过滤、排序等封装成Python的方法/属性调用
为什么我们要用它?
Model的定义
Model类必须写在django应用的models.py文件里,且必须继承自django.db.models.Model。
第一个完整的Model
我们先写一个文章管理Model,覆盖基础字段、通用字段选项、__str__方法和Meta类:
from django.db import models
from django.utils import timezone # 推荐用django内置的时区处理工具
class Article(models.Model):
# 字段定义(通用字段选项放在参数里)
title = models.CharField(
max_length=200, # CharField必须加的必填项
null=False, # 数据库层面不允许为NULL
blank=False, # 表单验证层面不允许为空(和null配合使用更严谨)
help_text="文章标题(最多200字)" # 后台/admin/表单会显示的提示文本
)
content = models.TextField(help_text="文章正文内容")
pub_date = models.DateTimeField(
"发布时间", # 可选的第一参数,指定字段在后台/admin的显示名
default=timezone.now # 默认值设为当前时间
)
author = models.CharField(max_length=100)
views = models.IntegerField(default=0, help_text="文章阅读量")
# __str__方法:定义实例在Python终端、后台/admin的显示文本
def __str__(self):
return f"《{self.title}》 - {self.author}"
# Meta类:定义Model的「元数据」(表名、排序、后台显示名等)
class Meta:
ordering = ["-pub_date"] # 默认按发布时间倒序排列(减号表示倒序)
verbose_name = "文章" # 后台/admin显示的单数名
verbose_name_plural = "文章" # 后台/admin显示的复数名(中文一般单数复数一致)
高频常用字段类型
django内置了几十种字段类型,覆盖了绝大多数开发场景,这里列最常用的:
数据库迁移
Model类只是Python层面的「数据结构描述」,要让它真正变成数据库里的表,必须执行迁移(Migration)操作。
迁移的两步核心流程
1. 生成迁移文件(makemigrations)
这一步会检测models.py的变化,并生成一个Python脚本文件(存放在对应应用的migrations文件夹里),这个脚本是「可逆的」,不用担心改坏表结构。
# 生成所有应用的迁移文件
python manage.py makemigrations
# 生成指定应用的迁移文件(推荐,更精准)
python manage.py makemigrations blog # 假设你的应用叫blog
2. 执行迁移(migrate)
这一步会读取迁移文件,并把它翻译成SQL语句,真正在数据库里创建/修改/删除表。
# 执行所有未应用的迁移
python manage.py migrate
# 执行指定应用的迁移
python manage.py migrate blog
常用的迁移辅助命令
查看迁移状态
# 查看所有应用的迁移文件状态([X]表示已应用,[ ]表示未应用)
python manage.py showmigrations
# 查看指定应用的迁移状态
python manage.py showmigrations blog
回滚迁移
# 回滚到指定的迁移版本(比如blog应用的0001_initial)
python manage.py migrate blog 0001_initial
# 回滚到迁移前的状态(删除该应用的所有表)
python manage.py migrate blog zero
QuerySet基础操作
Model类的objects属性是django自动生成的管理器(Manager),所有的数据库操作都要通过它来调用,返回的结果是一个QuerySet(可以理解为「延迟执行的查询集」,只有在真正用到数据的时候才会去数据库查,性能很高)。
创建记录(Create)
方法1:save()
先实例化Model类,再手动调用save()方法,适合需要修改实例属性后再保存的场景。
from blog.models import Article
from django.utils import timezone
# 1. 实例化
article = Article(
title="django Model入门教程",
content="今天我们来学习django的Model层...",
author="张三",
pub_date=timezone.now()
)
# 2. 手动修改属性(可选)
article.views = 10
# 3. 保存到数据库
article.save()
方法2:create()
直接通过管理器的create()方法创建并保存,适合不需要额外修改属性的场景,代码更简洁。
Article.objects.create(
title="django ORM的优势",
content="django ORM有跨数据库兼容、防SQL注入等优势...",
author="李四"
)
查询记录(Retrieve)
获取所有记录
# 返回所有Article的QuerySet
all_articles = Article.objects.all()
获取单个记录
注意:get()方法必须返回且只能返回一条记录,如果没有或有多个,会抛出异常。
# 用主键id查询(最常用)
article = Article.objects.get(id=1)
# 用其他唯一字段查询(比如unique=True的slug)
# article = Article.objects.get(slug="django-model-intro")
获取第一条/最后一条记录
# 按默认排序(Meta里的ordering)取第一条
first_article = Article.objects.first()
# 按默认排序取最后一条
last_article = Article.objects.last()
过滤查询(filter())
filter()方法返回符合条件的多条记录的QuerySet,支持链式调用。
# 查询作者是张三的文章
zhang_articles = Article.objects.filter(author="张三")
# 查询2024年发布的文章(双下划线__表示字段查询操作)
2024_articles = Article.objects.filter(pub_date__year=2024)
# 链式调用:查询2024年发布、作者是张三的文章
zhang_2024_articles = Article.objects.filter(author="张三").filter(pub_date__year=2024)
更新记录(Update)
更新单个记录
和save()创建记录的流程类似,先查询到实例,修改属性后再save()。
article = Article.objects.get(id=1)
# 修改属性
article.title = "django Model入门教程(升级版)"
article.views += 1 # 阅读量加1
# 保存
article.save()
批量更新
直接通过filter()+update()方法,不需要先查询实例,效率更高,适合修改大量符合条件的记录。
# 把所有作者是张三的文章的阅读量加100
Article.objects.filter(author="张三").update(views=models.F("views") + 100)
# 注意:批量更新不能用普通的Python变量,要用models.F()来引用数据库里的字段值
删除记录(Delete)
删除单个记录
先查询到实例,再调用delete()方法。
article = Article.objects.get(id=1)
article.delete()
批量删除
直接通过filter()+delete()方法,不需要先查询实例,效率更高。
# 删除所有2022年之前发布的文章
Article.objects.filter(pub_date__lt="2022-01-01").delete()
课程总结
今天我们从ORM的定位入手,学习了:
- 如何用Python类定义一个完整的django Model
- 高频常用的字段类型和通用字段选项
- 数据库迁移的两步核心流程和辅助命令
- QuerySet的基础CRUD操作(创建、查询、更新、删除)
这些都是django开发的核心基础,熟练掌握它们后,我们就可以进一步学习Model的关联关系、高级查询、性能优化等内容啦~