Home > Back-end >  How to Update value of a Model with another Model's value in Django
How to Update value of a Model with another Model's value in Django

Time:02-03

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?

CodePudding user response:

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.

CodePudding user response:

You're most likely looking for Django Signals. You'd want your Trade model's create event to trigger a post_save signal that a listener will receive and process.

Assuming you have saved your models in a file models.py,

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.

in your 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**
  • Related