How to Update value of a Model with another Model's value in Django
class Trade(models.Model): pips = models.FloatField(default=0) direction = models.CharField(max_length=30) new_balance = FloatField(default=0.0) ... class Summary(models.Model): winning_trades = models.IntegerField(default=0) account_balance = FloatField(default=0.0) ...
When a user post a request he/she will populate the Trade model, this will update the summary model and send back to the user new summary data. How can I do this in an elegant way?
First, I will encourage you to create a transaction to perform these two actions. If the second one fails, your database will remain consistent.
Then, Django allows you to override the model methods such as
save. You should try that with something like the following:
class Trade(): ... def save(self, *args, **kwargs): with transaction.atomic(): super.save() update_summary()
Then, in the view, you could query for the recently updated
Summary and return it.
class TradeViewSet(): def create(self, request, *args, **kwargs): user = request.user trade = Trade.create(request.data) updated_summary = get_summary(user.id) response = SummarySerializer(updated_summary) return Response(response)
Hope it helps you.
You're most likely looking for Django Signals. You'd want your
create event to trigger a
post_save signal that a listener will receive and process.
Assuming you have saved your models in a file
Create a file
signals.py with the following:
# code from django.db.models.signals import post_save from django.dispatch import receiver from .models import Trade, Summary @receiver(post_save, sender=Trade) def update_summary(sender, instance, created, **kwargs): if created: # query to update Summary as needed
You'll have to add the signals to your app config.
apps.py of the relevant app, add the following:
from django.apps import AppConfig class AppnameConfig(AppConfig): name = 'appname' **def ready(self): import appname.signals**