Reputation: 18705
I'm trying to create a simple signal which creates an identifier for the model.
class Scheduler(models.Model):
weekhours = models.ManyToManyField('WeekHour', related_name='schedulers')
identificator = models.TextField(null=True,blank=True)
class WeekHour(models.Model):
hour = models.PositiveSmallIntegerField(verbose_name='Hour in week (0 - 7*24')
Everytime when Scheduler
object is saved, I want to create or update the identificator
joining a list of [weekhour_obj.hour for weekhour_obj in scheduler.weekhours.all()]
So I created a post_save
signal. The problem is that when I save Scheduler
, the signal acts like it was pre_save
. The workhours
set for the scheduler is the old one, not updated. When I save it second time it works.
@receiver(post_save,sender=models.Scheduler)
def set_identificator(sender,created,instance,**kwargs):
identificator = ','.join([str(x.hour) for x in instance.weekhours.all().order_by('hour')])
models.Scheduler.objects.filter(pk=instance.pk).update(identificator = identificator)
Do you know where is the problem?
EDIT - Example:
When I put print instance.weekhours.all()
to the first line in the signal method it acts this way:
<QuerySet [<WeekHour: 2>,<WeekHour: 4>]>
<QuerySet [<WeekHour: 5>]>
But it is a post_save
signal so why it acts like it was pre_save
?
Upvotes: 1
Views: 587
Reputation: 1232
Many-to-many
relationships require the parent object to be saved first , You can’t associate items with a Scheduler
instance until it’s been saved.
In your example you are trying to get instance.weekhours.all()
in post_save
but it will return always None
in the first save
. for that you need to do another save to get values.
You can use m2m_changed instead of post_save
to create the identificator
Upvotes: 3