Django ORM – 单表实例(长文讲解)

Django ORM – 单表实例:从零开始掌握数据库操作

在 Django 开发中,Django ORM(对象关系映射)是一个非常核心的工具。它让你可以用 Python 代码来操作数据库,而不用写原生 SQL。对于初学者来说,掌握 Django ORM – 单表实例 是迈向高效开发的第一步。今天,我们就来手把手带你理解什么是 ORM,如何在单个数据表中进行增删改查操作,以及这些操作背后的逻辑。

如果你曾经被 SQL 语句搞得头大,或者觉得数据库操作太繁琐,那么 Django ORM 就是你的救星。它把数据库表变成 Python 类,把记录变成对象,让你用写代码的方式去操作数据。


什么是 ORM?用“翻译官”比喻它

你可以把 ORM 想象成一位“翻译官”。数据库里存的是结构化的数据,而你写的是 Python 代码。ORM 就是那个把你的 Python 语句翻译成 SQL 语句,再交给数据库执行的人。

比如你写 User.objects.create(name="张三", age=25),ORM 会自动帮你生成一条 INSERT INTO user (name, age) VALUES ('张三', 25) 的 SQL 语句。你不用关心底层怎么执行,只要关注“我要做什么”。

这种抽象大大降低了开发门槛,也提升了代码的可读性和可维护性。


创建模型:把数据库表变成 Python 类

在 Django 中,模型(Model)是 ORM 的核心。每个模型对应数据库中的一张表。

假设我们要做一个简单的用户管理系统,需要保存用户的姓名和年龄。首先,在 models.py 文件中定义一个 User 模型:

from django.db import models

class User(models.Model):
    # 用户名字段,最大长度 50 个字符
    name = models.CharField(max_length=50)
    
    # 年龄字段,整数类型
    age = models.IntegerField()
    
    # 创建时间,自动记录创建时间
    created_at = models.DateTimeField(auto_now_add=True)
    
    # 修改时间,每次保存都会更新
    updated_at = models.DateTimeField(auto_now=True)
    
    # 定义模型的中文名称(用于 Django Admin 界面)
    class Meta:
        verbose_name = "用户"
        verbose_name_plural = "用户列表"

这段代码中:

  • models.CharField 表示字符串字段,max_length=50 限制长度。
  • models.IntegerField 用于存储整数。
  • auto_now_add=True 表示首次创建时自动填充当前时间。
  • auto_now=True 表示每次保存时自动更新时间。
  • Meta 类用于设置模型的元信息,比如在后台管理界面显示的名称。

⚠️ 注意:定义完模型后,必须执行迁移命令才能在数据库中创建表。


数据库迁移:让模型“落地”成表

Django 要求你通过迁移(Migration)来同步模型与数据库结构。

在终端执行以下命令:

python manage.py makemigrations

这会生成一个迁移文件,记录你的模型变化。

接着执行:

python manage.py migrate

这一步会真正把 User 模型转换为数据库中的 myapp_user 表(myapp 是你的应用名)。

✅ 小贴士:makemigrations 是“生成变更计划”,migrate 是“执行变更计划”。两者缺一不可。


增删改查操作:单表最常用的四种操作

现在数据库里已经有 User 表了,我们来实践 Django ORM – 单表实例 中最核心的增删改查操作。

创建数据:用 create() 插入新记录

插入一条新用户记录:

user = User.objects.create(
    name="李四",
    age=30
)

print(f"用户 {user.name} 已创建,ID: {user.id}")
  • User.objects.create() 是最常用、最简洁的创建方式。
  • 它会直接保存到数据库,无需手动调用 save()

查询数据:用 all()、get()、filter() 查找记录

查询所有用户

all_users = User.objects.all()

for user in all_users:
    print(f"ID: {user.id}, 姓名: {user.name}, 年龄: {user.age}")
  • all() 返回所有记录的 QuerySet(可以理解为“查询结果集”)。

查询单条记录:用 get()

try:
    user = User.objects.get(id=1)
    print(f"找到用户: {user.name}, 年龄: {user.age}")
except User.DoesNotExist:
    print("未找到该用户")
  • get() 只返回一条记录。如果没找到,会抛出 DoesNotExist 异常。
  • 一定要用 try-except 捕获异常,避免程序崩溃。

查询多条记录:用 filter()

older_users = User.objects.filter(age__gt=25)

zhang_users = User.objects.filter(name__startswith="张")

age_range_users = User.objects.filter(age__range=(20, 30))

for user in older_users:
    print(f"年龄大于 25: {user.name}")
  • filter() 返回的是 QuerySet,可以链式调用。
  • __gt 表示“大于”,__startswith 表示“以...开头”,__range 表示“在范围内”。

💡 比喻:filter() 就像在超市里用筛选器挑商品,age__gt=25 就是“只选价格大于 25 的”。


更新数据:修改对象并 save()

更新操作需要先查询,再修改,最后保存。

user = User.objects.get(id=1)

user.age = 31
user.name = "李四(更新版)"

user.save()

print(f"用户 {user.name} 的年龄已更新为 {user.age}")
  • save() 方法会执行 UPDATE 语句。
  • 也可以使用 update() 方法批量更新,但需要配合 filter()
User.objects.filter(age__lt=30).update(age=models.F('age') + 1)
  • models.F('age') 表示引用字段本身,避免读取-修改-写入的竞态问题。

删除数据:用 delete() 删除记录

user = User.objects.get(id=1)
user.delete()

print("用户已删除")
  • delete() 会执行 DELETE 语句。
  • 也可以批量删除:
User.objects.filter(age__lt=18).delete()

⚠️ 删除操作不可逆,请谨慎使用!


QuerySet 的延迟执行机制:你真的懂它吗?

一个非常重要的概念:Django ORM 的 QuerySet 是延迟执行的

这意味着你写 User.objects.filter(age__gt=25) 时,数据库还没执行查询。只有当真正用到数据时,比如遍历、取第一个、转成列表等,才会生成 SQL 并执行。

queryset = User.objects.filter(age__gt=25)

for user in queryset:
    print(user.name)

first_user = queryset.first()

✅ 好处:避免不必要的查询,提升性能。 ❌ 坏处:如果写错逻辑,可能产生 N+1 查询问题。


实际案例:构建一个简单的用户管理功能

我们来模拟一个完整的使用场景:添加用户、列出所有用户、修改用户信息。

def add_user(name, age):
    User.objects.create(name=name, age=age)
    print(f"用户 {name} 添加成功")

def list_users():
    users = User.objects.all()
    if users.exists():
        for user in users:
            print(f"ID: {user.id}, 姓名: {user.name}, 年龄: {user.age}")
    else:
        print("暂无用户")

def update_user_age(user_id, new_age):
    try:
        user = User.objects.get(id=user_id)
        user.age = new_age
        user.save()
        print(f"用户 {user.name} 年龄已更新为 {new_age}")
    except User.DoesNotExist:
        print("用户不存在")

def delete_user(user_id):
    try:
        user = User.objects.get(id=user_id)
        user.delete()
        print(f"用户 {user.name} 已删除")
    except User.DoesNotExist:
        print("用户不存在")

这个小功能完整展示了 Django ORM – 单表实例 的实际应用。你可以把它放进视图函数里,配合 Django 的路由和模板使用。


总结:掌握单表操作,迈向 ORM 高手

今天我们一起深入学习了 Django ORM – 单表实例 的核心内容:

  • 如何定义模型,把数据库表变成 Python 类;
  • 如何使用迁移命令让模型“落地”;
  • 四大基本操作:创建、查询、更新、删除;
  • 理解 QuerySet 的延迟执行机制,避免性能陷阱;
  • 通过实际案例,掌握如何在项目中使用 ORM。

这些知识是 Django 开发的基石。当你熟练掌握单表操作后,就可以轻松应对多表关联、复杂查询等进阶内容。

📌 记住:ORM 的本质是“用代码操作数据库”。你写的每一段代码,最终都会变成一条 SQL 语句。理解这一点,你就能写出高效、安全、可维护的代码。

如果你觉得这篇教程对你有帮助,不妨收藏起来,作为日常开发的参考手册。下一期,我们将会讲解多表关联与外键操作,敬请期待。