Django中如何重写save()方法

前言:

在Django的开发过程中,有时会需要我们重写save()方法来实现某些应用场景,下面来聊一聊如何重写save()方法以及一些注意事项

在model中重写

先抛出一个应用的场景:

  • 我们的模型用于存储文章,里面有文章标题,内容,创建时间,修改时间
  • 需要在每次保存时更新修改时间

定义如下:

python 复制代码
class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_time = models.DateTimeField(auto_now_add=True)
    updated_time = models.DateTimeField(null=True)

创建时间会在生成时自动生成,更新时间由我们编写逻辑,且允许为空


使用模板:

python 复制代码
def save(self,*args,**kwargs):
    # 编写保存前的逻辑
    super().save(*args,**kwargs)
    # 编写保存后的逻辑

super().save(*args,**kwargs)是父类的保存逻辑

我们是在父类的保存逻辑基础上添加逻辑

不能舍弃父类的保存逻辑


现在的需求:由于修改时间是每一次保存的时候都需要更新,抓住关键词,保存[save()方法]。就可以翻译为每一次调用save()方法时都需要更新修改时间字段


需求明确了,那只需要在每次保存之前都把修改时间设置为当前时间即可

实现:

python 复制代码
def save(self,*args,**kwargs):
    self.updated_time = timezone.now()
    super().save(*args,**kwargs)

测试:

python 复制代码
article = models.Article(title='django中的save方法',content='这是内容')
article.save()

更新:

python 复制代码
article = models.Article.objects.get(title='django中的save方法')
article.content = '这是修改的内容'
article.save()

注意:如果此处你使用.filter.update()更新数据,此时不会调用save()方法

为了演示此处用.get().字段名重新赋值调用save()方法演示

可以看见修改时间处已经更新

在ModelForm中重写

还是先抛出一个应用的场景:

  • 我们需要把不合规的昵称换为"系统昵称"
  • 需要在保存是检查昵称并进行操作

模版语法:

python 复制代码
def save(self, commit=True):
    instance = super().save(commit=False)
    # ---- 此处编写保存逻辑
		
   	# ----
    if commit:
        instance.save()
    return instance

补充讲解:

注意如果同时调用
instance.username


self.cleaned_data['username']

此时两个的值是一样的,因为在
instance = super().save(commit=False)

时,就是利用了cleaned_data创建的instance实例对象

因为保存的时候是instance.save(),所以保存到数据库的时候

是以instance的数据

结合我之前的一篇文章可以得出总结

Django表单数据处理cleaned_data['*']和instance.*获取/修改数据的区别

save方法中会利用cleaned_data创建实例对象

在创建实例对象之前:

修改cleaned_data数据会影响到数据库

创建实例对象后:

修改instance对象才会影响到数据库

所以在创建好instance对象后修改cleaned_data不会影响到数据库

因为保存到数据库中的是利用cleaned_data创建的实例对象,在创建好实例对象后再修改已经没用了


回到正题,此时

为代码添加如下操作

python 复制代码
def save(self, commit=True):
    instance = super().save(commit=False)
    if instance.username == '不合规的昵称':
        instance.username = '系统昵称'
    if commit:
        instance.save()
    return instance

即可:

相关推荐
探索宇宙真理.13 分钟前
SeaCMS SQL注入漏洞 | CVE-2025-15002 复现&研究
数据库·sql·开源·海洋cms
writeone13 分钟前
【无标题】
数据库·oracle
+VX:Fegn089523 分钟前
计算机毕业设计|基于springboot + vue英语学习系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
_OP_CHEN25 分钟前
【C++数据结构进阶】从 Redis 底层到手写实现!跳表(Skiplist)全解析:手把手带你吃透 O (logN) 查找的神级结构!
数据结构·数据库·c++·redis·面试·力扣·跳表
名誉寒冰29 分钟前
Redis 常用数据结构与实战避坑指南
数据结构·数据库·redis
少云清29 分钟前
【接口测试】1_PyMySQL模块 _数据库操作应用场景
数据库·代码实现
spssau31 分钟前
正交试验设计全解析:从正交表生成到极差与方差分析
数据库·算法·机器学习
山峰哥32 分钟前
SQL性能瓶颈破局:Explain分析+实战优化全攻略
大数据·数据库·sql·oracle·性能优化
幺零九零零33 分钟前
Redis容器了解Docker底层
数据库·redis·docker
Vic1010135 分钟前
【无标题】
java·数据库·分布式