The question in general is about finding the modification of a foreign key of a model and call some function of the related model.
Assume I have two model class:
class Discount(models.Model):
def use(self, sell_item):
if self.max_price:
self.max_price -= sell_item.net()
if self.max_count:
self.max_count -= sell_item.amount
self.save()
def deuse(self, sell_item):
if self.max_price:
self.max_price += sell_item.net()
if self.max_count:
self.max_count += sell_item.amount
self.save()
max_price = models.PositiveIntegerField(blank=True,
null=True)
max_count = models.PositiveIntegerField(blank=True,
null=True)
amount = models.PositiveIntegerField(blank=False,
null=False)
class SellItem(models.Model):
def net(self):
price = self.amount * self.price
if self.discount:
price -= self.discount.amount * price / 100
return price * (1 + self.tax / 100)
amount = models.PositiveIntegerField(balnk=False,
null=False)
price = models.PositiveIntegerField(blank=False,
null=False)
tax = models.PositiveIntegerFeidl(blank=False,
null=False)
discount = models.ForeignKey(Discount,
blank=True,
null=True)
Now I want to execute use
function whenever a discount add to an item and deuse
it whenever it is being removed from an item. I found a post about it and to do that I write below code for sell item:
def __init__(self, *args, **kwargs):
self.dirty = False
self.pre_states = []
self.new_states = []
super(SellItem, self).__init__(*args, **kwargs)
def __setattr__(self, name, value):
if name == 'discount':
if hasattr(self, name):
pre_discount = self.discount
if pre_discount != value:
self.dirty = True
if pre_discount:
self.pre_states = ['pre_discount']
self.pre_discount = pre_discount
if value:
self.new_states = ['discount']
object.__setattr__(self, name, value)
def save(self, *args, **kwargs):
super(SellItem, self).save(*args, **kwargs)
if self.dirty:
if 'pre_discount' in self.pre_states:
self.pre_discount.deuse(self)
if 'discount' in self.new_states:
self.discount.use(self)
But it is not enough, because basically django would not fetch a foreign key when a new class is constructed, it instead just fill the _id item for it and whenever you need that it would fetch it from database, if I check for modification of discount_id
instead of discount
based on the order of setting of member values I may miss the previous discount
because I have just current and previous discount_id
not discount
.
I know that it could possible implement with checking all of cases but I think after all I depend on django implementation of the behavior of database fetching which could be changed further.
I think there must be a proper and easier solution for just knowing the modification of a foreign key, I know there is some packages for storing history of modification but they are too much for my simple request.