美文网首页
django 自定义.save()方法

django 自定义.save()方法

作者: eeert2 | 来源:发表于2020-05-03 17:27 被阅读0次

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
        )

相关文章

网友评论

      本文标题:django 自定义.save()方法

      本文链接:https://www.haomeiwen.com/subject/aindghtx.html