3

After creating a model object I would like to use a post_save signal to populate another model field in the same object with the ID and other values.

But the real question here is, how do i access the field from the instance? nothing worked

Example: User creates an object -> id of the object is 93 -> I would like to add #00093 as value of another field in the same object.

models.py

class Ticket(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    designation = models.CharField(max_length=255, blank=True, null=True)
    summary = models.CharField(max_length=255)

signals.py

@receiver(post_save, sender=Ticket)
def ticket_designation(sender, instance, **kwargs):
    instance.designation = "#" + "000" + str(instance.id)
    print("Ticket" + instance.designation + " was created.")
xxbinxx
  • 1,527
  • 11
  • 18
Manko
  • 91
  • 8

1 Answers1

7

I think you really want to do this:

@receiver(post_save, sender=Ticket)
def ticket_designation(sender, instance, created, **kwargs):
    if created:
        designation = "#" + "000" + str(instance.id)
        Ticket.filter(pk=instance.pk).update(designation=designation)
        print("Ticket" + instance.designation + " was created.")

Explanation:

why use if created: designation is only created once when the new Ticket is created. It's not updated every time you save the same object.

why use Ticket.objects.filter(..).update(..) : we cannot do instance.save() as it'll then call this post_save again and recursion occurs. .update on queryset does not call signals so we're safe.


If you want to use instance.save you might want to look at how to prevent post_save recursion in django.

Rosi98
  • 107
  • 9
xxbinxx
  • 1,527
  • 11
  • 18
  • nice it worked, i had to tune it fully for my customization purposes, but i got the hang out of it thanks to your filter + update recommendation, thanks very much have a nice day! – Manko May 29 '19 at 13:18