Django中如何重写save()方法
前言:
在Django的开发过程中,有时会需要我们重写save()方法来实现某些应用场景,下面来聊一聊如何重写save()方法以及一些注意事项
在model中重写
先抛出一个应用的场景:
- 我们的模型用于存储文章,里面有文章标题,内容,创建时间,修改时间
- 需要在每次保存时更新修改时间
定义如下:
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)
创建时间会在生成时自动生成,更新时间由我们编写逻辑,且允许为空
使用模板:
def save(self,*args,**kwargs):# 编写保存前的逻辑super().save(*args,**kwargs)# 编写保存后的逻辑
super().save(*args,**kwargs)是父类的保存逻辑
我们是在父类的保存逻辑基础上添加逻辑
不能舍弃父类的保存逻辑
现在的需求:由于修改时间是每一次保存的时候都需要更新,抓住关键词,保存[save()方法]。就可以翻译为每一次调用save()方法时都需要更新修改时间字段
需求明确了,那只需要在每次保存之前都把修改时间设置为当前时间即可
实现:
def save(self,*args,**kwargs):self.updated_time = timezone.now()super().save(*args,**kwargs)
测试:
article = models.Article(title='django中的save方法',content='这是内容')
article.save()

更新:
article = models.Article.objects.get(title='django中的save方法')
article.content = '这是修改的内容'
article.save()

注意:如果此处你使用
.filter.update()更新数据,此时不会调用save()方法
为了演示此处用.get().字段名重新赋值调用save()方法演示
可以看见修改时间处已经更新
在ModelForm中重写
还是先抛出一个应用的场景:
- 我们需要把不合规的昵称换为"系统昵称"
- 需要在保存是检查昵称并进行操作
模版语法:
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创建的实例对象,在创建好实例对象后再修改已经没用了
回到正题,此时
为代码添加如下操作
def save(self, commit=True):instance = super().save(commit=False)if instance.username == '不合规的昵称':instance.username = '系统昵称'if commit:instance.save()return instance
即可:

