django|django 自定义.save()方法
在django
中,我们有时候需要自己控制数据库的存储。这就需要我们重写模型的.save()
方法。
【django|django 自定义.save()方法】一般来说,我们可以这样写:
class Student(models.Model):
username = models.CharField('学生姓名', max_length=16)
age = models.IntegerField('年龄')def save(self, *args, **kwargs):
do_something()
super().save(*args, **kwargs)# 执行真正的 .save() 方法.
do_something_else()
一、举个例子,使用
do_something_else()
的场景:
我们创建订单,订单有一个编号the_id
是根据创建日期和主键pk
生成的。class Order(models.Model):def _create_the_id(self):
"""生成订单编号"""
return self.created.date().strftime('%Y%m%d') + '_' + str(self.id)created = models.DateTimeField('创建时间', auto_now_add=True)
the_id = models.CharField('订单编号', max_length=32, unique=True, null=True)
title = models.CharField('订单名称', max_length=32, default='')
total = models.FloatField('订单金额', default=0.0)
在这里,我们的
the_id
属性依赖于id
,所以我们必须先执行.save()
然后再进行更新。>>> order = Order(title='订单的标题****', total=25.5)
>>> order.save()# 保存进数据库,获取 id>>> order.the_id = order._create_the_id()
>>> order.save() # 更新 the_id 属性
这里就有一个问题,我们需要在每个
.save()
执行后都执行>>> order.the_id = order._create_the_id()
更好的方法是重写
.save()
方法def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
# 执行 save(), 将数据保存进数据库
super().save(
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields
)
self.the_id = self._create_the_id()# 再次执行 save(), 将数据更新到数据库
# 注意这里的参数,必须设置 force_update=True,否则会创建新的数据
super().save(
force_insert=False,
force_update=True,
using=using,
update_fields=['the_id']
)
当我们重写
.save()
后,就不用考虑会不会忘记执行更新the_id
操作了。现在直接执行.save()
就会自动帮我们更新the_id
二、在
.save()
之前执行do_something()
在数据库中,有些属性属于派生属性
,也就是说它们是依据其它属性生成的。class Order(models.Model):
created = models.DateTimeField('创建时间', auto_now_add=True)
title = models.CharField('订单名称', max_length=32, default='')
num = models.IntegerField('商品数量')
price = models.FloatField('商品价格')
total = models.FloatField('订单金额', default=0.0)
在上述
订单模型
中,total
应该是在后端存储时自动计算,而不是接收前端传给我们的数据。def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):self.total = self.num * self.price# 执行 save(), 将数据保存进数据库
super().save(
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields
)
推荐阅读
- SpringBoot调用公共模块的自定义注解失效的解决
- python自定义封装带颜色的logging模块
- django-前后端交互
- 列出所有自定义的function和view
- Spring|Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件
- 自定义MyAdapter
- django2.2|django2.2 一般项目步骤(初步)
- Android自定义view实现圆环进度条效果
- Flutter自定义view|Flutter自定义view —— 闯关进度条
- js保留自定义小数点