0
votes

I have general question. Let’s say I have a model field that is the sum of two other fields in a different model.

I’m having a hard time to implement this. Let’s take the following example

model1 field1 field2

model2 field3 (dependent on field1 and field2) in model1

If I do it as part of specific page in my webapp. It means that if field1 or field2 has changed but the person didn’t visit the page that sum up the value and update it in field3 then field3 will carry incorrect value.

The only way to takle such a problem that I managed to identify is to never create field3. everytime a sum(or any other operation that had dependency on other fields) take a place is to be done in a variable inside the view.py

This means that value to be calculated everytime it is needed.

This way I won’t get myself in a position where I forget to recalculate the value of field3.

My question is this the best way to do it? Is there a way that whenever a depedent field change such as field1 that automatically change field3 without the need to visit a specific page?

I tried something with foriegn keys for field3 and try to add the value of two foriegn key inside the model.py but I don’t think it is allowed.

field3 = field1+ field2

any suggestions?

**

  • added the following example per request to further clarify question

If you notice that the totalPrice under transaction table is based on the price for the item and shipping. However, this require visiting order.html page.

My question if someone changed the item that resulted in a different price. Then without visiting the order.html page the totalprice in transaction table won't reflect the new price. Is there a way to build the "transaction" model in a way that updates the totalprice if any other field it depends on was updated without the need to visit the order.html page?

**

models.py

class Item(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    price = models.FloatField(null=True)

class Shipping(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    price = models.FloatField(null=True)

class Transaction(models.Model):
     user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
     total_price = models.FloatField(null=True)

views.py
def order(request):
    item_obj = item.object.get(user=self.user)
    ship_obj = shipping.object.get(user=self.user)
    trans_obj = transaction.object.get(user=self.user)

    trans_obj.total_price = item_obj.price + ship_obj.price
    trans_obj.save()
    return render(request, 'order.html')
1
You should be able to override the save function in model1 and add the behaviour there, but it depends on how they're linked together. However this sounds like a unusual design pattern, if you share your full models it might be possible to solve another way.Johan
It sounds like you want a database view...?thebjorn
Added code to clarify my question. Thanks!Khaled Nakawa

1 Answers

-1
votes

You can override save function in Shipping and Item models.

def save(self, *args, **kwargs):
    #change total_price
    # Transaction.save(update_fields['total_price'])
    super(Item, self).save(*args, **kwargs)

However "#change total_price" will depend on how you are going to relate your models and how you're going to find proper Shipping object