0

These are my models:

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)

This is my signal:

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

I want to pass a pre_save signal of the same as I have done in my post_save signal i.e. I want to perform a pre_save signal function instead of a post_save signal..

When I try to do using pre_save signal I get the following error:

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

Any idea how to do this?

Thank you

Niladry Kar
  • 1,163
  • 4
  • 20
  • 50

2 Answers2

0

You are assigning unsaved stockitem(Stockdata) object to a OneToOneField and thus it raises an error.

When you are assigning stockitem(Stockdata) object to OneToOneField, Id is not generated as you haven't saved stockitem object and thus as error says it will cause a data loss while saving Stock_journal model.

Aniket Pawar
  • 2,641
  • 19
  • 32
  • 1
    It will not work for pre_save signal as Stockdata haven't saved yet. While in post_save you have Stockdata instance which saved in database. – Aniket Pawar Apr 19 '19 at 06:37
0

pre_save has different arguments than post_save. When you use created, you are actually using raw.

At that point when you call for Stock_journal.objects.create, you instance is not even saved (i.e. exist in database), thus you can't use instance in Stack_journal creation.

More about raw from django docs:

raw - A boolean; True if the model is saved exactly as presented (i.e. when loading a fixture). One should not query/modify other records in the database as the database might not be in a consistent state yet.

Gasanov
  • 2,839
  • 1
  • 9
  • 21
  • I know `pre_save` signals have diffrent argument, I have used this for `pre_save` `(sender,instance,*args,**kwargs)` – Niladry Kar Apr 19 '19 at 06:35
  • Well it doesn't really matter, if you are trying to save related object, referring to instance, you going to have this problem - django can't save it without knowing instance `id`, and it doesn't know it because `instance` is not in database yet. That's why `post_save` works. – Gasanov Apr 19 '19 at 06:38