1

我正在寻找一种方法来更改历史记录中的额外字段。

我有一个模型InvoiceBalance.

class UserBalanceHistoricalModel(models.Model):

    invoice = models.ForeignKey('Invoice', null=True, blank=True, on_delete=models.SET_NULL,
                                verbose_name='Faktúra')

    class Meta:
        abstract = True

class UserBalance(TimeStampedModel):
    objects = UserBalanceManager()
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
                                related_name='user_balance', verbose_name='Užívateľ')
    balance = models.DecimalField(max_digits=12, decimal_places=2, default=0, verbose_name="Eur na konte")
    history = HistoricalRecords(bases=[UserBalanceHistoricalModel, ])

class Invoice(models.Model):
    ...

每次Invoice创建对象时,都会对其UserBalance.balance进行修改并自动创建历史记录。

我想将此Invoice对象添加到历史记录中,但它不起作用。invoice_idNone。_

In [10]: u = User.objects.first()

In [11]: i = Invoice.objects.first()

In [12]: balance = u.user_balance

In [13]: balance.balance = 45 

In [16]: balance.history.invoice = i

In [18]: balance.save()

In [28]: balance.history.all().values_list('invoice_id',flat=True)
Out[28]: <QuerySet [None, None, None, None]>

你知道我做错了什么吗?

4

1 回答 1

2

balance.history正在访问HistoryManagerbalance 类,它本质上是历史模型的管理器,而不是历史模型实例本身。因此,该行balance.history.invoice = i只是在管理器类上设置了一个局部变量,没有任何效果。实际的历史模型实例不会创建,直到 balance 用balance.save(). 您要做的是访问pre_create_historical_record信号,该信号在balance保存之后但在保存历史实例之前发送。这在此处记录。

对于您的用例,您可以为信号设置一个接收器,该pre_create_historical_record信号接收并使用您想要的任何值history_instance编辑该字段。invoice您可以在基础对象上传递发票,然后像这样删除它:

# in apps.py
def add_invoice_to_historical_balance(sender, instance, historical_instance, **kwargs):
    historical_instance.invoice = instance.invoice
    del instance.invoice

class BalanceConfig(AppConfig):
    def ready(self):
        from ..models import HistoricalUserBalance

        pre_create_historical_record.connect(
             add_invoice_to_historical_balance,
             sender=HistoricalUserBalance,
             dispatch_uid='add_invoice_to_historical_balance'
        )

您上面的代码如下所示:

In [10]: u = User.objects.first()

In [11]: i = Invoice.objects.first()

In [12]: balance = u.user_balance

In [13]: balance.balance = 45 

In [16]: balance.invoice = i

In [18]: balance.save()
于 2018-12-12T19:50:11.650 回答