Home > front end >  Django aggregate sum of manytomany is adding up everything in its field instead of the ones selected
Django aggregate sum of manytomany is adding up everything in its field instead of the ones selected

Time:03-17

2 Classes involved in question class Appointment and class Service

appointmentApp.models class Service

class Service(models.Model):
    service_name = models.CharField(max_length=15, blank=False)
    service_time = models.IntegerField(blank=False)
    
    def __str__(self):
        return self.service_name

    class Meta:
        verbose_name_plural = "Services"

appointmentApp/models.py class Appointment

class Appointment(models.Model):
    service_chosen = models.ManyToManyField(Service, blank=False)
    total_time = models.IntegerField(blank=False, null=False, default=0)

    #will add up the amount of time needed for each service
    def save(self, *args, **kwargs):
        self.total_time  = Service.objects.all().aggregate(total_time=Sum('service_time'))['total_time']
        super(Appointment, self).save(*args, **kwargs)

    def __str__(self):
        return self.client_dog_name

Services are chosen through a multiplechoice field and on save the service_chosen's service_time are added up

but what my save function is doing instead is adding up all the existing service.service_time instead of the ones selected, why is this happening?

CodePudding user response:

ManyToManyFields are saved after the containing instance is saved, you need to create a signal handler to perform this update on m2m_changed

from django.db.models.signals import m2m_changed


class Appointment(models.Model):
    ...


def service_chosen_changed(sender, instance=None, action=None, **kwargs):
    if action == 'post_add':
        instance.total_time = instance.service_chosen.aggregate(total_time=Sum('service_time'))['total_time']
        instance.save()

m2m_changed.connect(service_chosen_changed, sender=Appointment.service_chosen.through)
  • Related