Django 模型(Model)是与数据库交互的核心层,遵循 MVC/MVT 架构中的 Model 层,其创建、修改、删除的处理过程需遵循 Django 的 ORM 规则和数据库迁移机制。以下是详细的分步解析,包含核心概念、操作流程和最佳实践。

一、核心前置概念

  1. ORM(对象关系映射):Django 模型将 Python 类映射到数据库表,类属性映射到表字段,实例对象映射到表行,无需直接写 SQL。
  2. 迁移(Migrations):Django 记录模型变更并同步到数据库的机制,通过 migrate/makemigrations 命令实现。
  3. app 依赖:模型必须属于某个 Django 应用(app),且 app 需在 settings.pyINSTALLED_APPS 中注册。

二、模型的创建过程

步骤 1:创建/注册 Django 应用(若未创建)

# 创建 app(例如名为 blog)
python manage.py startapp blog

# 在 settings.py 中注册 app
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    ...,
    'blog',  # 新增
]

步骤 2:定义模型类(models.py

模型类继承 django.db.models.Model,字段类型对应数据库列类型,支持丰富的字段选项(如主键、非空、默认值等)。

示例:创建一个博客文章模型

# blog/models.py
from django.db import models
from django.utils import timezone

class Article(models.Model):
    # 字段定义:字段类型 + 字段选项
    title = models.CharField(max_length=200, verbose_name="标题", help_text="文章标题")
    content = models.TextField(verbose_name="内容")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    is_published = models.BooleanField(default=False, verbose_name="是否发布")

    # 可选:自定义元数据(表名、排序、verbose_name 等)
    class Meta:
        db_table = "blog_article"  # 自定义数据库表名(默认是 app名_模型名)
        ordering = ["-create_time"]  # 默认按创建时间降序排列
        verbose_name = "文章"
        verbose_name_plural = "文章"

    # 可选:自定义实例展示名称
    def __str__(self):
        return self.title

步骤 3:生成迁移文件(记录模型变更)

迁移文件保存在 app 的 migrations 目录下,是模型变更的“日志”,描述如何修改数据库表。

# 检测模型变更并生成迁移文件
python manage.py makemigrations

# 可选:指定 app 生成迁移(避免检测所有 app)
python manage.py makemigrations blog

# 可选:查看迁移文件对应的 SQL 语句(验证正确性)
python manage.py sqlmigrate blog 0001  # 0001 是迁移文件的编号

步骤 4:执行迁移(同步到数据库)

将迁移文件的变更应用到数据库,创建对应的表/字段。

# 执行所有未应用的迁移
python manage.py migrate

# 可选:指定 app 执行迁移
python manage.py migrate blog

步骤 5:验证模型创建

  • 查看数据库:表 blog_article 已创建,字段与模型定义一致;
  • 通过 Django Shell 验证:

    python manage.py shell
    from blog.models import Article
    # 创建实例(插入数据)
    article = Article(title="Django 模型教程", content="核心步骤解析")
    article.save()  # 保存到数据库
    # 查询验证
    Article.objects.all()  # 返回 [<Article: Django 模型教程>]

三、模型的修改过程

模型修改包括 字段增删、字段属性修改、Meta 配置修改 等,核心流程是:修改模型 → 生成迁移 → 执行迁移。

场景 1:新增字段

Article 新增 author 字段(字符串类型,允许为空):

# blog/models.py
class Article(models.Model):
    ...
    author = models.CharField(max_length=50, null=True, blank=True, verbose_name="作者")  # 新增字段

执行迁移:

python manage.py makemigrations  # 生成迁移文件(会提示是否设置默认值,按需选择)
python manage.py migrate        # 同步到数据库,表新增 author 列

场景 2:修改现有字段

title 字段的 max_length 从 200 改为 255:

title = models.CharField(max_length=255, verbose_name="标题", help_text="文章标题")  # 修改 max_length

执行迁移:

python manage.py makemigrations
python manage.py migrate  # 数据库中 title 列的长度会更新

场景 3:删除字段

删除 is_published 字段:

# blog/models.py
class Article(models.Model):
    title = models.CharField(max_length=255, verbose_name="标题")
    content = models.TextField(verbose_name="内容")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    author = models.CharField(max_length=50, null=True, blank=True, verbose_name="作者")
    # is_published 字段已删除

执行迁移:

python manage.py makemigrations
python manage.py migrate  # 数据库中 is_published 列被删除(注意:数据会丢失!)

注意事项:

  • 修改字段时若涉及 非空约束、数据类型变更(如 CharField → IntegerField),需确保数据兼容,或设置默认值;
  • 生产环境修改模型前,建议先备份数据库;
  • 若迁移文件生成错误,可删除 migrations 目录下的新文件(未执行 migrate 时),重新生成。

四、模型的删除过程

模型的删除分为两种场景:删除模型类(整表删除)删除模型实例(数据行删除)

场景 1:删除整个模型类(删除数据库表)

步骤:

  1. 删除 models.py 中的 Article 类;
  2. 生成迁移文件(Django 会检测到模型被删除,提示是否删除表);
  3. 执行迁移,数据库中对应的表会被删除(数据全部丢失!谨慎操作)。

示例:

# 删除 models.py 中的 Article 类后
python manage.py makemigrations  # 提示:Delete model Article
python manage.py migrate        # 数据库中 blog_article 表被删除

场景 2:删除模型实例(数据行删除)

通过 Django ORM 删除单条/多条数据(不修改模型结构,仅操作数据):

# 方式 1:删除单个实例
article = Article.objects.get(id=1)  # 查询 id=1 的文章
article.delete()  # 删除该实例,数据库中对应行被删除

# 方式 2:批量删除
Article.objects.filter(author__isnull=True).delete()  # 删除作者为空的所有文章

# 方式 3:删除所有实例
Article.objects.all().delete()  # 清空表数据(表结构保留)

五、迁移的高级操作

1. 回滚迁移(撤销模型变更)

若迁移执行后发现错误,可回滚到上一个迁移版本:

# 查看迁移历史(找到要回滚的目标版本)
python manage.py showmigrations blog

# 回滚到指定版本(格式:app名 迁移版本号)
python manage.py migrate blog 0001  # 回滚 blog app 到 0001 版本(0001 是迁移文件前缀)
注意:回滚会撤销数据库变更(如删除新增的字段/表),需确保数据安全。

2. 重置迁移(重新初始化)

若迁移文件混乱,可重置迁移(适用于开发环境):

# 1. 清空数据库中该 app 的迁移记录(django_migrations 表)
python manage.py dbshell
DELETE FROM django_migrations WHERE app = 'blog';

# 2. 删除 app 的 migrations 目录下的所有文件(保留 __init__.py)
# 3. 重新生成初始迁移
python manage.py makemigrations blog

# 4. 执行迁移(--fake-initial 避免重复创建表)
python manage.py migrate blog --fake-initial

六、最佳实践总结

  1. 模型设计

    • 字段命名遵循小写+下划线(如 create_time),避免关键字;
    • 合理设置字段选项(null=True/blank=True 区分数据库/表单验证,default 设置默认值);
    • Meta 自定义表名、排序、索引等,提升查询效率。
  2. 迁移管理

    • 每个模型变更都要生成迁移文件,不要手动修改数据库;
    • 迁移文件需纳入版本控制(如 Git),团队协作时同步迁移;
    • 生产环境执行 migrate 前,先在测试环境验证。
  3. 数据安全

    • 删除字段/模型前备份数据;
    • 批量删除数据时先通过 filter 验证查询结果,再执行 delete
    • 避免直接修改已上线的核心字段类型(如从 CharField 改为 TextField 需评估影响)。
  4. 性能优化

    • 为常用查询字段添加索引(models.Indexdb_index=True);
    • 避免冗余字段,通过外键/关联关系复用数据;
    • 批量操作使用 bulk_create/bulk_update 代替循环 save()

七、常见问题

  1. 迁移提示“没有检测到变更”

    • 检查模型修改是否正确,或是否忘记保存 models.py
    • 确认 app 已注册到 INSTALLED_APPS
    • 尝试删除 migrations 目录下的 __pycache__ 文件。
  2. 执行 migrate 时报错“表已存在”

    • 使用 --fake-initial 参数标记初始迁移为已执行:python manage.py migrate --fake-initial
  3. 字段修改后数据丢失

    • 避免直接删除字段,若需保留数据可先备份,或设置 null=True 后逐步清理。

通过以上流程,可规范完成 Django 模型的创建、修改、删除,确保模型与数据库的一致性,同时保障数据安全和系统稳定性。
(来自豆包)

标签: none