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**