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

Posted

技术标签:

【中文标题】Django:覆盖保存(模型或管理部分)【英文标题】:Django: Overriding the Save (Either Model or Admin Section) 【发布时间】:2016-04-28 04:52:18 【问题描述】:

我最近一直在玩 Django,但是我一直在思考如何解决这个问题。我有一个“人”模型,它与“凭证”模型具有一对多的关系。现在这个人有一个配额,每次生成一个 Voucher,配额就会减少一个。我坚持的是通过 save 方法做到这一点。那么如何做到这一点呢?

以下是我的模型:

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')

【问题讨论】:

【参考方案1】:

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

幸运的是,我很快检查了尚刚给我看的文档(并且还看得更深)。方法如下:

@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()

当然我必须做更多的事情(简单的验证和类似的东西),但这就是我需要的。

【讨论】:

【参考方案2】:

为了避免重复使用凭证计数信息,我会稍微降低性能(请称我为老式)。

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

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

【讨论】:

【参考方案3】:

不要在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 信号。

【讨论】:

它还没有工作,但你现在把我带到了正确的方向,所以我感谢你,如果我让它工作,那么也发布代码。我赞成你的回答,因为它显示了从这里开始的其他地方

以上是关于Django:覆盖保存(模型或管理部分)的主要内容,如果未能解决你的问题,请参考以下文章

Django - 覆盖模型保存()

Django-CMS - 当我指定模型时,管理员的 CMS 部分消失

Django:保存模型时填充用户 ID

Django 抽象父模型保存覆盖

姜戈。覆盖模型的保存

在第一次保存对象时使 django 模型字段只读或在管理员中禁用