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

即可:

相关推荐
zgl_2005377911 小时前
源代码:跨数据库通用SQL语法解析与标注拆解
大数据·数据库·数据仓库·sql·etl·源代码管理
雪度娃娃12 小时前
存储器层次结构——磁盘硬盘存储
服务器·网络·数据库·计算机组成原理
暴力求解12 小时前
Mysql数据库基础
数据库·mysql·操作系统
意倾城12 小时前
MySQL最左前缀匹配原则
数据库·mysql
暴躁小师兄数据学院12 小时前
【AI大数据工程师特训笔记】第13讲:数据库性能手术刀
大数据·数据库·数据仓库·sql·postgresql
步十人13 小时前
【Redis】持久化机制
数据库·redis·缓存
Quincy_Freak14 小时前
银河麒麟aarch64如何高效做数据分析?分享一款内网离线数据分析利器
大数据·数据库·数据挖掘·数据分析·aarch64
香气袭人知骤暖14 小时前
PG数据库 Docker 容器自动备份方案
数据库·docker·容器
me83214 小时前
【Linux】Linux 目录命名规范溯源(Linux各个目录究竟是干嘛的)
linux·运维·数据库
土狗TuGou15 小时前
SQL内功笔记 · 第2篇:列的约束
数据库·笔记·sql