Reputation: 8782
The question is honestly pretty self-explanatory. I have 2 models which are related. It goes like this:
from django.db import IntegrityError, transaction
class Item(models.Model):
total_score = models.IntegerField()
def set_score(self):
...
class Review(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
score = models.IntegerField()
def save(self, *args, **kwargs):
try:
with transaction.atomic():
super(Review, self).save(*args, **kwargs)
self.item.set_score()
except IntegrityError:
handle_exception()
Basically, whenever a review is saved, its item's score is updated using the set_score()
method. I put the whole thing in an atomic transaction because obviously, I don't want a review to update and the item's score to remain un-updated. Thats like a breeding ground for potential bugs. Anyway, is the right way to do it? I feel like I have no way of testing this in my local server as it is impossible to create an error which saves the review but not update the score. Thanks.
Note: I know there are better ways to handle the score of an item based on its reviews. That is not the point of the question. It is a made up scenario for the sake of explaining what I want to do. So, please, no answers mentioning that.
Upvotes: 1
Views: 1760
Reputation: 3707
Yes, you could do it as you have mentioned but it is better to use business logic/ transaction logic outside of save() method. This would provide you better integrity and also abstraction.
Writing this logic inside save function is shorthand to do (pretty easy).
other way to do this
utils.py
def update_score(*args, **kwargs):
with transaction.atomic():
review = Review(*args, **kwargs)
review.item.set_score()
review.save()
If this wouldn't helpful for you than writing that transaction block inside save() method or simply pick your code into other method and wrap that with exception but handle that try-catch block with proper exception because it makes side effects / Buggy code. Rest of the things would be fine and work.
Just remember that do not handle exceptions inside the transaction atomic block.
Upvotes: 3