I am generating a reference number to an objects field. If the record is new, the signal will fill other fields before saving. If the record is not new, I also have an action for it. I will check for an objects specific field and see if it changed and do some other action.
Here is a snippet of the signal function:
@receiver(pre_save, sender=ProofOfPayment)
def pre_save_for_proof_of_payment(sender, instance, created=False, **kwargs):
print('created', created)
if created:
upload_date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
reference_number = 'PAYMENT-' + upload_date
instance.reference_number = reference_number
received = PaymentStatus.objects.get(pk=1) # Received
instance.payment_status = received
else:
obj = sender.objects.get(pk=instance.pk)
if not obj.payment_status == instance.payment_status:
if instance.payment_status.name == 'Completed':
instance.expiry_date = datetime.datetime.now() + datetime.timedelta(days=30)
I am simulating the process in the admin. I create a new record. When I create the new object, I get an error because the variable created
is set to False
, doing the else function in the snippet.
obj = sender.objects.get(pk=instance.pk)
ProofOfPayment matching query does not exist.
I am not sure why the created
value is set to False
even if the record is new.
When I don't place a default value in the function:
def pre_save_for_proof_of_payment(sender, instance, created, **kwargs):
I get this error:
pre_save_for_proof_of_payment() missing 1 required positional argument: 'created'
When I set the default value to created=True
, the signal does not get triggered when new record is made.
I am confused on how to use the created
argument. What I knew is that Django will provide the boolean value based on if the record is new or not. But in this case, it is taking the default value once a new record is created.
What should be my default created boolean value such that I know when there is a new record as such in the if created:
code block and when the record is not new such to trigger actions such as in the else
codeblock.
My model goes like this.
class ProofOfPayment(models.Model):
reference_number = models.CharField(max_length=500, blank=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL)
payment_type = models.ForeignKey(
PaymentType,
on_delete=models.SET_NULL,
null=True,
blank=True,)
payment_status = models.ForeignKey(
PaymentStatus,
on_delete=models.SET_NULL,
null=True,
blank=True,)
receipt = models.FileField(
upload_to='userproofofpayment',
null=True,
max_length=500)
remarks = models.TextField(max_length=250, blank=True)
upload_date = models.DateTimeField(auto_now_add=True)
expiry_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.reference_number
You don't have created
argument in pre_save
signal. You have to use post_save
for such logic.
How can it say that's the object is created, when it's not saved yet?