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

即可:

相关推荐
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希4 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神4 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员5 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴5 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU5 小时前
三大范式和E-R图
数据库