Django. Override save for model
Some thoughts:
class Model(model.Model):
_image=models.ImageField(upload_to='folder')
thumb=models.ImageField(upload_to='folder')
description=models.CharField()
def set_image(self, val):
self._image = val
self._image_changed = True
# Or put whole logic in here
small = rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
def get_image(self):
return self._image
image = property(get_image, set_image)
# this is not needed if small_image is created at set_image
def save(self, *args, **kwargs):
if getattr(self, '_image_changed', True):
small=rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
super(Model, self).save(*args, **kwargs)
Not sure if it would play nice with all pseudo-auto django tools (Example: ModelForm, contrib.admin etc).
Django override save method: to return super().save() or not to return?
You should not use return super().save(*args, **kwargs)
. Because save method does not return anything in Django's models.Model
class. Here is the reference to GitHub repository. So you should always use:
def save(self, *args, **kwargs):
#some code
super().save(*args, **kwargs)
# some more code
how to override django save method to update some field dynamically?
Solution One:
I think instead of changing in Ledger
model, you should change in Expense
model, like this:
class Expense(models.Model):
...
def save(self, *args, **kwargs):
self.payment_option.amount_to_pay = self.payment_option.amount_to_pay + self.amount_to_pay
self.payment_option.save()
super(Expense, self).save(*args, **kwargs)
Solution Two:
But to be honest, Solution One does not seem good to me. Reason is that you are saving same data in 2 places(in both expense and ledger). Instead, it should be once, then the amount_to_pay
value in Ledger
should be calculated dynamically. Like this:
from django.db.models import Sum
class Ledger(...):
@property
def amount_to_pay(self):
# I am using a property method to show the amount_to_pay value.
# FYI: in this way, you need to remove amount_to_pay field from Ledger model
return self.opening_balance - self.expense_set.all().aggregate(a_sum=Sum('amount_to_pay')).get('a_sum', 0)
In that way, with each ledger, the value amount_to_pay
will be dynamically calculated at runtime. For example:
for l in Ledger.objects.all():
l.amount_to_pay
Solution Three:
If you are wary of making DB hits with each l.amount_to_pay
(as it calculates amount_to_pay from DB dynamically) from previous solution, then you can always annotate
the value. Like this:
For this solution, you need to change your Expense
model and add a related_name
:
class Expense(models.Model):
pay_from = models.CharField(max_length=200)
payment_option = models.ForeignKey('Ledger', on_delete=models.CASCADE, related_name='expenses')
Then use that related_name
in query like this(FYI: You can't keep def amount_to_pay(...)
method in Ledger model for the following usage example):
from django.db.models import Sum, F, ExpressionWrapper, IntegerField
ledgers = Ledger.objects.all().annotate(expense_sum=Sum('expenses__amount_to_pay')).annotate(amount_to_pay=ExpressionWrapper(F('opening_balance') - F('expense_sum'), output_field=IntegerField()))
# usage one
for l in ledgers:
l.amount_to_pay
# usage two
ledgers.values('amount_to_pay')
Overriding Django ModelForm save method and deleting old values(files)
Try using this, it works just fine in terms of auto deleting old files and pictures.
https://pypi.org/project/django-cleanup/
Related Topics
Python Re.Sub Group: Number After \Number
Pythonic Way to Check If a List Is Sorted or Not
Pandas Dataframe to List of Lists
What Exactly Does "Import *" Import
Rewrite Multiple Lines in the Console
Importerror: No Module Named 'Encodings'
Working with an Access Database in Python on Non-Windows Platform (Linux or MAC)
String Replace Doesn't Appear to Be Working
Why Does the Print Function Return None
How to Install Packages Using Pip According to the Requirements.Txt File from a Local Directory
Differencebetween an Expression and a Statement in Python
Pandas: Multiple Conditions While Indexing Data Frame - Unexpected Behavior
Difference Between Class and Instance Methods
Finding All Possible Permutations of a Given String in Python
Split Cell into Multiple Rows in Pandas Dataframe