django 自定義.save()方法

django中,我們有時候需要自己控制數(shù)據(jù)庫的存儲。這就需要我們重寫模型的.save()方法。

一般來說,我們可以這樣寫:

class Student(models.Model):
    username = models.CharField('學(xué)生姓名', max_length=16)
    age = models.IntegerField('年齡')

    def save(self, *args, **kwargs):
        do_something()
        super().save(*args, **kwargs)  # 執(zhí)行真正的 .save() 方法.
        do_something_else()

一、舉個例子,使用do_something_else()的場景:

我們創(chuàng)建訂單,訂單有一個編號the_id是根據(jù)創(chuàng)建日期和主鍵pk生成的。

class Order(models.Model):

    def _create_the_id(self):
        """生成訂單編號"""
        return self.created.date().strftime('%Y%m%d') + '_' + str(self.id)

    created = models.DateTimeField('創(chuàng)建時間', 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,所以我們必須先執(zhí)行.save()然后再進(jìn)行更新。

>>> order = Order(title='訂單的標(biāo)題****', total=25.5)
>>> order.save()  # 保存進(jìn)數(shù)據(jù)庫,獲取 id

>>> order.the_id = order._create_the_id()
>>> order.save() # 更新 the_id 屬性

這里就有一個問題,我們需要在每個.save()執(zhí)行后都執(zhí)行

>>> order.the_id = order._create_the_id()

更好的方法是重寫.save()方法

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        # 執(zhí)行 save(), 將數(shù)據(jù)保存進(jìn)數(shù)據(jù)庫
        super().save(
            force_insert=force_insert,
            force_update=force_update,
            using=using,
            update_fields=update_fields
        )
        self.the_id = self._create_the_id()

        # 再次執(zhí)行 save(), 將數(shù)據(jù)更新到數(shù)據(jù)庫
        # 注意這里的參數(shù),必須設(shè)置 force_update=True,否則會創(chuàng)建新的數(shù)據(jù)
        super().save(
            force_insert=False,
            force_update=True,
            using=using,
            update_fields=['the_id']
        )

當(dāng)我們重寫.save()后,就不用考慮會不會忘記執(zhí)行更新the_id操作了?,F(xiàn)在直接執(zhí)行.save()就會自動幫我們更新the_id

二、在.save()之前執(zhí)行do_something()

在數(shù)據(jù)庫中,有些屬性屬于派生屬性,也就是說它們是依據(jù)其它屬性生成的。

class Order(models.Model):
    created = models.DateTimeField('創(chuàng)建時間', auto_now_add=True)
    title = models.CharField('訂單名稱', max_length=32, default='')
    num = models.IntegerField('商品數(shù)量')
    price = models.FloatField('商品價(jià)格')
    total = models.FloatField('訂單金額', default=0.0)

在上述訂單模型中,total應(yīng)該是在后端存儲時自動計(jì)算,而不是接收前端傳給我們的數(shù)據(jù)。

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):

        self.total = self.num * self.price

        # 執(zhí)行 save(), 將數(shù)據(jù)保存進(jìn)數(shù)據(jù)庫
        super().save(
            force_insert=force_insert,
            force_update=force_update,
            using=using,
            update_fields=update_fields
        )
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容