def get_sum_sizes(instance):
"""
Суммирует размеры файлов инстанса (FileField, ImageField и любые
производные FileField)
"""
sized_fields = (f.attname for f in instance._meta.fields if isinstance(f, models.FileField))
def get_size(field):
f = getattr(instance, field)
return f and f.size or 0
return sum(get_size(f) for f in sized_fields)
@receiver(post_init)
def store_old_files_size(instance, **kwargs):
"""
К инстансу, у которого есть атрибут клиники
дописывается сумма байтов, занимаемых файлами инстанса
"""
if getattr(instance, 'clinic_id', None) is None:
return
instance.__old_files_size = get_sum_sizes(instance)
@receiver(post_save)
def update_clinic_files_size(instance, created, **kwargs):
if not created and not hasattr(instance, '__old_files_size'):
return
if created:
instance.__old_files_size = 0
clinic = getattr(instance, 'clinic', None)
append = get_sum_sizes(instance) - instance.__old_files_size
if append and clinic:
Clinic.objects.filter(pk=clinic.pk).update(files_size=F('files_size') + append)
@receiver(pre_delete)
def update_clinic_files_size_delete(instance, **kwargs):
"""Удалённые файлы не занимают место"""
if not hasattr(instance, '__old_files_size'):
return
clinic = instance.clinic
subtract = get_sum_sizes(instance)
if subtract:
Clinic.objects.filter(pk=clinic.pk).update(files_size=F('files_size') - subtract)