Reputation: 4192
I have a Django model that overrides the save method and looks like this:
class Log(models.Model):
agent = models.ForeignKey(Agent, on_delete=models.CASCADE)
calls_logged = models.IntegerField(default=0)
texts_logged = models.IntegerField(default=0)
completed_logs = models.BooleanField(default=False, db_index=True)
def save(self, *args, **kwargs):
if self.calls_logged >= 30 and self.texts_logged >= 50:
self.completed_logs = True
super().save(*args, **kwargs)
What's supposed to happen is when the Agent
reaches 30 calls and 50 texts, the save()
method is supposed to change the completed_logs
field to True
. But when I recently checked my DB, an agent had reached over 30 calls and over 50 texts but completed_logs
wasn't marked as completed. However, when I clicked 'Save' from within the admin, it updated the completed_logs
field as expected.
So, my question is: is there ever a time that Django will not call the save()
method on a model? Is there a better way to do this?
Upvotes: 1
Views: 1225
Reputation: 21817
There are some methods that can update entries in the database without calling the save
method. Some of which I can think of are:
update
method of a querysetbulk_create
method of a querysetbulk_update
method of a querysetMost likely the situation is that you call one of these methods, causing this situation to occur.
The best thing to do here is to not have completed_logs
as a field but rather as a property:
class Log(models.Model):
agent = models.ForeignKey(Agent, on_delete=models.CASCADE)
calls_logged = models.IntegerField(default=0)
texts_logged = models.IntegerField(default=0)
@property
def completed_logs(self):
return self.calls_logged >= 30 and self.texts_logged >= 50
Upvotes: 4