美文网首页
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