Reputation: 6831
I have a model Entry
Now whenever Entry
is created for any date. Then before saving I need to make check and add more entries, for example e.g.
Entry 1 - red
Now suppose if any entry.color = red
Then I also need to make two more entries like
Entry 2 - red2
Entry 3 - red3
Now I have put this in pre_save signal
@receiver(pre_save, sender=Entry)
def new_entries(sender, instance, *args, **kwargs):
pass
Now my problem is this ends in infinite recursion as those new entries which I want to save also send pre_save signal and this loop never finishes.
Where do put this logic so that recursion does not occur?
Upvotes: 3
Views: 1849
Reputation: 297
In post_save singal in django for avoiding recursion 'if created' check is required
from django.dispatch import receiver
from django.db.models.signals import post_save
@receiver(post_save, sender=DemoModel)
def _post_save_receiver(sender,instance,created, **kwargs):
if created:
print('hi..')
instance.save()
Upvotes: 0
Reputation: 17506
I would solve it with an additional argument to save, as opposed to attaching to pre_save:
import django.db.models
class Entry(models.Model):
color=models.CharField(max_length="50")
def save(self,create_children=True,**kwargs):
if create_children and not self.pk:
result = super(Entry,self).save(**kwargs)
Entry(color=self.color).save(create_children=False)
Entry(color=self.color).save(create_children=False)
else:
result = super(Entry,self).save(**kwargs)
return result
You want to make sure you call super(Entry,self).save(**kwargs)
before you actually construct the children, otherwise you will clutter the database with models when super() raises an IntegrityError
Upvotes: 4
Reputation: 1639
I think you should have 2 separate models for this. Your 'parent' Entry
could be a subclass of the main Entry
model so that only IT creates new child Entries.
class Entry(models.Model):
pass
# whatever you need here
class ParentEntry(Entry):
@receiver(pre_save, sender=ParentEntry)
def new_entries(sender, instance, *args, **kwargs):
pass
The reason for adding another model is that these models actually do 2 different things, 1 creates more when creating, 1 does not. For clarity, I would prevent situations where 1 model's constructor can do 2 separate things.
Upvotes: 0
Reputation: 12641
something like this should work:
class Entry(model.Model):
def save(self, color, create_more=True, *args, **kwargs):
if self.pk is None: # this is a new Entry
if create_more:
new_color = '%s2' % color
Entry(color=new_color, create_more=False).save()
super(Entry, self).save(...)
tho I suspect there is a better way, but I can't say without knowing more details of what you are trying to do.
Upvotes: 0