【问题标题】:Saving model instance using pre_save signal使用 pre_save 信号保存模型实例
【发布时间】:2019-09-09 11:04:16
【问题描述】:

这些是我的模型:

class Stockdata(models.Model):
    user        = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True,related_name='user_stock')
    company     = models.ForeignKey(Company,on_delete=models.CASCADE,null=True,blank=True)
    stock_name  = models.CharField(max_length=32)

class Stock_journal(models.Model):
    user                = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True,related_name='user_closing')
    company             = models.ForeignKey(Company,on_delete=models.CASCADE,null=True,blank=True)
    stockitem           = models.OneToOneField(Stockdata,on_delete=models.CASCADE,null=True,blank=True,related_name='closingstock')
    closing_stock       = models.DecimalField(max_digits=10,decimal_places=2,null=True)

这是我的信号:

@receiver(post_save, sender=Stockdata)
def create_default_stock_ledger(sender, instance, created, **kwargs):
    if created:
        Stock_journal.objects.create(user=instance.User,company=instance.Company,stockitem=instance)

我想传递与我在 post_save 信号中所做的相同的 pre_save 信号,即我想执行 pre_save 信号功能而不是 post_save 信号..

当我尝试使用 pre_save 信号时,我收到以下错误:

save() prohibited to prevent data loss due to unsaved related object 'stockitem'.

知道怎么做吗?

谢谢

【问题讨论】:

  • 您是否刚刚将post_save 替换为pre_save?它有不同的论点。
  • 是的,我使用 pre_save 做了同样的事情,这给了我错误信息

标签: django django-models django-signals


【解决方案1】:

您将未保存的 stockitem(Stockdata) 对象分配给 OneToOneField,因此会引发错误。

当您将 stockitem(Stockdata) 对象分配给 OneToOneField 时,不会生成 Id,因为您尚未保存 stockitem 对象,因此错误表示在保存 Stock_journal 模型时会导致数据丢失。

【讨论】:

  • 它不适用于 pre_save 信号,因为 Stockdata 尚未保存。在 post_save 中,您有 Stockdata 实例,该实例保存在数据库中。
【解决方案2】:

pre_save 具有 different arguments 而不是 post_save。当你使用created时,你实际上是在使用raw

当您调用Stock_journal.objects.create 时,您的实例甚至没有保存(即存在于数据库中),因此您不能在Stack_journal 创建中使用instance

来自 django 文档的更多关于 raw 的信息:

原始 - 一个布尔值;如果模型完全按照呈现方式保存(即加载夹具时),则为真。不应该查询/修改其他记录 数据库作为数据库可能尚未处于一致状态。

【讨论】:

  • 我知道pre_save 信号有不同的参数,我已经将它用于pre_save (sender,instance,*args,**kwargs)
  • 好吧,没关系,如果你试图保存相关对象,引用实例,你会遇到这个问题 - django 无法在不知道实例 id 的情况下保存它,并且它不知道,因为instance 还没有在数据库中。这就是 post_save 起作用的原因。
猜你喜欢
  • 2019-08-17
  • 1970-01-01
  • 2017-04-07
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2011-12-22
  • 1970-01-01
相关资源
最近更新 更多