Django Model 数据更新的多种实现方式与注意事项

陆景行
陆景行
发布时间:2026-10-13| 6人浏览过
原创

本文详细介绍Django中Model数据更新的多种方法。涵盖常规字段批量与单条更新、auto_now字段的特殊处理、JSON字典数据的高效写入,以及ForeignKey和ManyToManyField字段的更新技巧与常见报错排查。

Django Model 数据更新的常规用法

Django Model 数据更新的常规用法

假设我们的数据库表结构如下定义:


class User(models.Model):
 username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
 is_active = models.BooleanField(default=False, verbose_name='激活状态')

若需修改用户名及激活状态,可采用以下两种主要方式:

第一种方法:


User.objects.filter(id=1).update(username='nick',is_active=True)

第二种方法:


_t = User.objects.get(id=1)
_t.username='nick'
_t.is_active=True
_t.save()

方法一适用于批量更新数据,其逻辑类似于 SQL 语句中的 update user set username='nick' where id = 1。

方法二适用于单条数据的更新,且仅能处理一条记录。在仅需更新单条数据时,推荐采用此方式。此外,该方法还具备其他优势,后续内容将详细展开。

带有 auto_now 属性字段的更新机制

带有 auto_now 属性字段的更新机制

在实际开发中,我们通常会在模型表中添加三个默认字段:

  • 自增 ID:Django 默认已包含此字段。如上述建表语句所示,即使仅定义 username 和 is_active 两个字段,生成的表中也会自动包含一个自增 ID 字段。

  • 创建时间:用于标识记录的创建时刻,具备 auto_now_add 属性。在创建新记录时,系统会自动填充当前时间至该字段。

  • 修改时间:用于标识记录最后一次被修改的时间,具备 auto_now 属性。当记录发生任何变化时,系统会自动将当前时间填充至该字段。

具备 auto_now 字段的表结构示例如下:


class User(models.Model):
 create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
 update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
 username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
 is_active = models.BooleanField(default=False, verbose_name='激活状态')

若表中包含具有 auto_now 属性的字段,且期望其能自动更新,则必须使用方法二进行更新。否则,auto_now 字段将不会触发更新,具体表现为:


_t = User.objects.get(id=1)
_t.username='nick'
_t.is_active=True
_t.save()

JSON 或字典类型数据的字段更新

JSON 或字典类型数据的字段更新

当前主流的 Web 开发模式强调前后端分离,交互数据格式普遍采用 JSON。那么,如何以最少代码便捷地将 JSON 格式数据更新至数据库?同样可使用以下两种方法:

第一种方法:


data = {'username':'nick','is_active':'0'}
User.objects.filter(id=1).update(**data)
  • 值得注意的是,此方法无法自动更新具有 auto_now 属性字段的值。
  • 通常在变量前添加一个星号 (*) 表示该变量为元组或列表,添加两个星号 (**) 表示该参数为字典。

第二种方法:


data = {'username':'nick','is_active':'0'}
_t = User.objects.get(id=1)
_t.__dict__.update(**data)
_t.save()

与方法一相同,此方法也无法自动更新 auto_now 字段的值。

此处用到了 dict 的一个特定方法。

第三种方法:


_t = User.objects.get(id=1)
_t.role=Role.objects.get(id=3)
_t.save()

ForeignKey 外键字段的更新

ForeignKey 外键字段的更新

若模型表中包含 ForeignKey 外键字段,应如何进行更新?


class User(models.Model):
 create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
 update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
 username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
 is_active = models.BooleanField(default=False, verbose_name='激活状态')
 role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='角色')

第一种方法:


User.objects.filter(id=1).update(role=2)
  • 最简单的方式是直接将 role 字段设置为对应的 ID 值。
  • 当然,也可以使用字典作为参数进行更新:

User.objects.filter(id=1).update(**{'username':'nick','role':3})

第二种方法:


_role = Role.objects.get(id=2)
User.objects.filter(id=1).update(role=_role)
  • 也可以将实例对象赋值给 role 字段。
  • 同样,可以使用字典作为参数进行更新:

_role = Role.objects.get(id=1)
User.objects.filter(id=1).update(**{'username':'nick','role':_role})

第三种方法:


_t = User.objects.get(id=1)
_t.role=Role.objects.get(id=3)
_t.save()
  • 注意:此处 role 必须赋值为对象实例,不能直接写入 ID,否则将报错 "User.role" must be a "Role" instance。
  • 当使用字典作为参数进行更新时,存在一点差异,代码如下:

_t = User.objects.get(id=1)
_t.__dict__.update(**{'username':'nick','role_id':2})
_t.save()
  • ForeignKey 外键字段在字典中必须加上 `_id` 后缀,例如:{'role_id': 3}。
  • role_id 后必须跟随一个 ID 值(int 或 str 类型均可),而不能直接跟随 role 实例。

ManyToManyField 字段的更新

ManyToManyField 字段的更新

若模型表中包含 ManyToManyField 字段,更新操作又有何不同?


class User(models.Model):
 create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
 update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
 username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
 is_active = models.BooleanField(default=False, verbose_name='激活状态')
 role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='角色')
 groups = models.ManyToManyField(Group, null=True, verbose_name='组')

多对多(m2m)字段没有直接的更新方法,只能通过先清空再添加的方式来实现更新。


_t = User.objects.get(id=1)
_t.groups.clear()
_t.groups.add(*[1,3,5])
_t.save()

add():用于向 m2m 字段添加一个值。当需要添加多个值时,可使用列表,参考上述示例。

_t.groups.add(2) _t.groups.add(Group.objects.get(id=2))

remove():用于从 m2m 字段移除一个值。当需要移除多个值时,可使用列表,参考上述示例。

_t.groups.remove(2) _t.groups.remove(Group.objects.get(id=2))

clear():用于清空 m2m 字段的所有值。

以上关于 Django Model update 多种用法的介绍即为全部内容,希望能为大家提供参考,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。