Reputation: 129
I have such problem. For example, there is a field in my model class:
periodic_task = models.OneToOneField(PeriodicTask, null=True, blank=True)
I need to override the save()
method to set this field value:
def save(self, *args, **kwargs):
super(PostTweetSet, self).save(*args, **kwargs)
self.periodic_task = TaskScheduler.create(
'tweets.tasks.post_next_tweet', self.interval.period,
self.interval.every, args="[" + '"%s"' % str(self.pk) + "]")
You see that self.periodic_task
gets assigned after actually calling the super()
method. I did so, because of need to have a pk field (I use it in TaskScheduler
create method). On the other side, I need to update db-table for this model after setting this new field. If I call super()
once again, I'll get error about duplicating id. So, what can I do to make this work? Or I need to reconstruct my approach for this task at all? Thanks.
Upvotes: 1
Views: 10763
Reputation: 4140
If you don't want to use a signal, why not store the result of super()
and return it instead of the call itself?
def save(self, *args, **kwargs):
run_task = False
if not self.pk:
run_task = True
result = super().save(*args, **kwargs)
if run_task:
TaskScheduler.create(...)
return result
Upvotes: 0
Reputation: 6950
By providing some condition in the override save method
in model I have achieved same requirement.
In the question, requirement is to update the periodic_task
field after saving the model, so here is the sudo code structure I have followed:
class MyModel(models.Model):
periodic_task = models.OneToOneField(PeriodicTask, null=True, blank=True)
def save(self):
super(Asset, self).save()
if not self.periodic_task: # Checking if the section is not updated.
self.periodic_task = #code to update the field.
self.save() #again call the save.
Upvotes: 4
Reputation: 1516
I'd do it with a post-save signal.
If you can't or that's otherwise unappealing, you think about your requirement as two paths:
So something like (pseudocode):
def save(...):
if self.pk is None:
super(...)
self.save(...) # Call ourselves -- but this time, we'll have a primary key!
else:
... create your periodic task
super(...)
Upvotes: 7
Reputation: 20800
You can call super()
at the end of your save()
override. Here is an example using the slugify()
method. The slugify method turns a string into a slug by converting all characters to lowercase and spaces to dashes. Here's the code:
from django.template.defaultfilters import slugify
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Product, self).save(*args, **kwargs)
Upvotes: 0