Reputation: 323
I have two models in Django and I want to automatically create an object of History
when an object of Food
is created or updated and set the food_price
attribute of History
to the price
attribute of the created Food
object. My purpose is to have a history of food change price. How can I achieve that?
My models.py
is:
class Food(models.Model):
food_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=30, null=False, blank=False)
desc = models.TextField(max_length=200)
price = models.IntegerField(null=False, blank=False)
f_thumbnail = models.ImageField(upload_to=get_food_t_image_name)
DDD_data = models.ImageField(upload_to=get_food_d_image_name)
availability = models.BooleanField(default=True)
discount = models.IntegerField(default=0)
def __str__(self):
return '%s %s %s' % (self.name, self.category_id, self.price)
class History(models.Model):
id = models.AutoField(primary_key=True)
food_id = models.IntegerField()
food_price = models.IntegerField()
history_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s %s %s' % (self.id, self.food_id.name, self.food_id.price)
Thanks in advance.
Upvotes: 1
Views: 1321
Reputation: 2966
I think you have two ways.
__save__()
method in model.In django model, (models.Model
), there's __save__
method. When model object saves, you can do an additional feature that inherits this method.
For more information, please check official docs save()
signals
Django supports many signals including django.db.models.signals
. It includes pre_save
, post_save
, and so on. So before(after) saving model object, you can do sth in signals
.
Please check official docs signals
I think __save__()
method is more fit to your purpose. So your code will be...
class Food(models.Model):
food_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=30, null=False, blank=False)
desc = models.TextField(max_length=200)
price = models.IntegerField(null=False, blank=False)
f_thumbnail = models.ImageField(upload_to=get_food_t_image_name)
DDD_data = models.ImageField(upload_to=get_food_d_image_name)
availability = models.BooleanField(default=True)
discount = models.IntegerField(default=0)
def __str__(self):
return '%s %s %s' % (self.name, self.category_id, self.price)
def save(self, force_insert=False, force_update=False, *args, **kwargs):
# you can add this for only existing model object
if self.pk:
# You can check if only 'price' field changed
_original_food = Food.objects.get(id=self.pk)
if _original_food.price != self.price:
# do somthing here like saving history...
History.objects.create(food_id=self.id, food_price=self.price)
super(Food, self).save(force_insert, force_update, *args, **kwargs)
super(Food, self).save(force_insert, force_update, *args, **kwargs)
This is just example. You can add & modify your code. I hope it helps you.
Upvotes: 2