模型层 ORM
ORM 是 Django 非常核心的一部分。它的价值在于:让你可以用 Python 的方式操作数据库,而不是一上来就把大量 SQL 硬写在项目里。
这并不代表你以后可以完全不学 SQL,而是说 Django 给了你一种更自然、更工程化的方式来处理数据。
本节目标
- 理解模型和数据表之间的关系
- 学会定义 Django 模型
- 理解字段类型
- 学会配置数据库连接
- 学会执行迁移
- 学会使用 ORM 做增删改查
- 理解模型关系的基础概念
什么是模型
你可以先把模型理解成:
- Python 里的一个类
- 同时又对应数据库里的一张表
例如:
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
city = models.CharField(max_length=50)这段代码的大致意思是:
- 你定义了一个
Student类 - Django 会把它映射成数据库中的一张数据表
- 表中有
name、age、city这些字段
所以 Django 模型不是普通类,它带着“映射到数据库”的意义。
为什么 ORM 有价值
如果完全手写 SQL,你当然也能操作数据库,但项目一复杂后会遇到这些问题:
- SQL 很多,代码不够清晰
- 查询结果和 Python 对象之间切换麻烦
- 模型关系维护成本高
- 重复操作很多
ORM 的优势是:
- 用 Python 代码描述数据结构
- 用 Python 代码完成很多常见查询
- 让模型关系表达更自然
定义第一个模型
打开 models.py:
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
city = models.CharField(max_length=50)字段分别是什么意思
CharField(max_length=50):字符串字段,最大长度 50IntegerField():整数类型字段
这个模型表示:一条学生数据至少包含姓名、年龄、城市。
常见字段类型
字符串字段
models.CharField(max_length=100)适合:
- 姓名
- 标题
- 城市
长文本字段
models.TextField()适合:
- 文章正文
- 课程介绍
- 评论内容
整数字段
models.IntegerField()适合:
- 年龄
- 数量
- 排序值
布尔字段
models.BooleanField(default=False)适合:
- 是否发布
- 是否热门
- 是否启用
日期时间字段
models.DateTimeField(auto_now_add=True)适合:
- 创建时间
- 发布时间
一个更完整的模型示例
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
is_public = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)这个模型已经很接近真实项目中的文章表结构了。
配置数据库连接
如果你只是做最基础练习,Django 默认的 SQLite 就可以用。
但如果你要连接 MySQL,可以在 settings.py 中配置:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "study_db",
"USER": "root",
"PASSWORD": "123456",
"HOST": "127.0.0.1",
"PORT": "3306",
}
}这里分别表示:
- 使用 MySQL 引擎
- 数据库名
- 用户名
- 密码
- 主机地址
- 端口
如果是 SQLite,配置会简单得多,Django 默认就已经帮你准备好了。
模型写完后为什么还要迁移
很多初学者会误以为:我在 models.py 里写完模型,数据库里就自动有表了。
不是这样。
模型代码只是“描述结构”,真正同步到数据库,还需要执行迁移。
makemigrations 和 migrate
第一步:生成迁移文件
python manage.py makemigrations它的作用是:
- 发现模型变化
- 生成数据库结构变更说明
第二步:执行迁移
python manage.py migrate它的作用是:
- 把迁移真正应用到数据库
可以简单理解成:
makemigrations:生成变更计划migrate:执行变更计划
新增数据
方法一:直接创建
Student.objects.create(name="小明", age=18, city="上海")这条语句执行后,数据库里就会新增一条学生记录。
方法二:先创建对象再保存
stu = Student(name="小红", age=19, city="杭州")
stu.save()这两种方式都常见。
查询数据
查询全部
students = Student.objects.all()
for item in students:
print(item.name)输出结果示例:
小明
小红条件查询
students = Student.objects.filter(age__gte=18)这里的意思是:
- 查询年龄大于等于 18 的学生
查询单条
stu = Student.objects.get(id=1)
print(stu.name)如果数据库中 id=1 对应的是“小明”,输出可能是:
小明修改数据
stu = Student.objects.get(id=1)
stu.city = "深圳"
stu.save()这表示:
- 先查出一条记录
- 修改字段值
- 再保存回数据库
删除数据
stu = Student.objects.get(id=1)
stu.delete()执行后,这条记录会从数据库中删除。
一个完整的增删改查流程示例
新增
Student.objects.create(name="小刚", age=20, city="北京")查询
students = Student.objects.all()
for item in students:
print(item.name, item.city)输出示例:
小刚 北京修改
stu = Student.objects.get(name="小刚")
stu.city = "广州"
stu.save()删除
stu = Student.objects.get(name="小刚")
stu.delete()这就是最基础的 CRUD:
- Create
- Read
- Update
- Delete
模型关系
现实业务里,数据表之间往往不是孤立的。
例如:
- 一个分类下有多篇文章
- 一个作者写多篇文章
- 一篇文章可能对应多个标签
这时就需要关系字段。
一对多:ForeignKey
例如:
- 一个分类
- 多篇文章属于这个分类
class Category(models.Model):
name = models.CharField(max_length=50)
class Article(models.Model):
title = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE)这表示:
- 每篇文章对应一个分类
- 一个分类可以对应多篇文章
多对多:ManyToManyField
例如:
- 一篇文章可以有多个标签
- 一个标签也可以对应多篇文章
class Tag(models.Model):
name = models.CharField(max_length=30)
class Article(models.Model):
title = models.CharField(max_length=100)
tags = models.ManyToManyField(Tag)一对一:OneToOneField
例如:
- 一个用户对应一份详细资料
class UserProfile(models.Model):
user = models.OneToOneField("auth.User", on_delete=models.CASCADE)
phone = models.CharField(max_length=20)零基础阶段你先知道这些关系分别在表达什么即可,不必一上来就追求全会。
在 Django shell 中测试 ORM
调试 ORM 最方便的方式之一是:
python manage.py shell进入 shell 后可以直接写:
from users.models import Student
Student.objects.create(name="小明", age=18, city="上海")
Student.objects.all()这非常适合你练习模型操作。
常见错误
1. 改了模型,但没迁移
你改完 models.py 后,如果忘了:
python manage.py makemigrations
python manage.py migrate数据库结构就不会同步更新。
2. get() 查不到或查出多条
get() 适合查唯一结果,如果没有唯一性保障,可能会报错。
3. 字段类型选错
例如本来是长文本,却用了很短的 CharField;本来是布尔值,却用了字符串字段。
4. 忘记给 app 注册
如果 app 没有加入 INSTALLED_APPS,模型相关操作可能根本不会被 Django 正常识别。
练习题
练习 1
定义一个 Course 模型,包含:
- 课程名
- 价格
- 简介
练习 2
执行迁移,让数据库中真正生成对应数据表。
练习 3
在 Django shell 中新增 3 条课程数据。
练习 4
查询所有课程,并打印课程名。
练习 5
再定义一个 Teacher 模型,并尝试让课程和老师建立一对多关系。
本节小结
ORM 的核心意义,是让你用 Python 的方式描述和操作数据库。
你这一节最重要的收获应该是:
- 模型就是数据库表的 Python 表达
- 字段类型决定数据如何存储
- 模型变更后必须迁移
- ORM 可以完成基础增删改查
- 关系字段用于表达表与表之间的联系
只要这一层打牢,后面你做 Django 网站开发时,数据这一块就有了真正的抓手。