Django:覆盖保存(模型或管理部分)

Django: Overriding the Save (Either Model or Admin Section)

我最近一直在研究 Django,但是我一直在思考如何解决这个问题。我有一个 'Person' 模型,它与 'Voucher' 模型具有一对多关系。现在这个人有一个额度,每生成一张Voucher,这个额度就会减一。我所坚持的是通过保存方法来做到这一点。那么如何做到这一点呢?

以下是我的模型:

class Person(AbstractDetail):
# Note: Model to maintain information about Person
     vc = models.IntegerField(default = 3, verbose_name = 'Vouchers', 
     null = False, validators = [ validate_voucher ])

class Voucher(models.Model):
# Note: Model to maintain information about Voucher
     vc = models.CharField (max_length = 25, verbose_name = 'Voucher ID',
                     help_text = 'Voucher Identifier')
     ps = models.ForeignKey(Person, on_delete = models.CASCADE,
                       verbose_name = 'Person')

不要在save()里做,很容易和django搞混。尝试使用 django 信号 post_save():

from django.db.models.signals import post_save

@receiver(post_save, sender=Voucher)
def decrease_quota(sender, instance, created, *args, **kwargs):
    if created:
        instance.vc -= 1
        instance.save()

检查 django doc 是否有 Django 信号。

为了避免重复凭证计数信息,我会稍微降低性能(叫我 old-fashioned)。

我不会在 Person.vc 中保存代金券计数,而是在需要时通过在代金券对象管理器中为其创建一个函数来评估代金券计数:

def get_voucher_count(self, person):
    return self.filter(ps=person).count()

好的,我设法解决了(在 Shang Wang 和 Ytsen de Boer 的帮助下,我也很感激)。我这样做的方法是创建对象 Person 的实例并从那里拿走它。

幸运的是,我快速查看了 Shang 刚刚给我看的文档(并且看得更深入)。方法如下:

@receiver(post_save, sender = Voucher, dispatch_uid = "voucher_identifier")
def decrease_quota(sender, instance, **kwargs):
obj = Person.objects.get(pk = instance.ps.id)
if obj.vc < 4 and obj.vc > 0:
    obj.vc = obj.vc - 1
    obj.save()

当然我还需要做更多的工作(简单的验证和类似的东西),但这正是我所需要的。