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

即可:

相关推荐
SuperSpinach2 小时前
mysql 报错Authentication method ‘caching_sha2_password‘ is not supported.
数据库·mysql
R.lin2 小时前
MySQL 性能优化最佳实践
数据库·mysql·性能优化
北i2 小时前
TiDB 关联子查询去关联优化实战案例与原理深度解析
java·数据库·sql·tidb
清风6666662 小时前
基于单片机的智慧校园自动打铃系统设计
数据库·单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
linuxxx1103 小时前
Centos环境中Django项目中gunicorn的配置和使用
django·centos·gunicorn
JIngJaneIL4 小时前
就业|高校就业|基于ssm+vue的高校就业信息系统的设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·高校就业
CXH7284 小时前
nginx-file-server
运维·数据库·nginx
一 乐4 小时前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·小区互助系统
q***57745 小时前
Spring Boot 实战:轻松实现文件上传与下载功能
java·数据库·spring boot