Updating a field in django model with a one to many relationship. Need to over ride save method

I have two Django models in my models.py file named Cases and CaseItems. These have a one to many relationship where a Case can have multiple CaseItems. Below are my model classes.

class Item(models.Model):
    name = models.TextField(unique=True)
    # Price is in cents
    price = models.PositiveIntegerField(
        validators=[
            MinValueValidator(1)
        ]
    )
    img = models.TextField()


class Case(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid4)
    name = models.TextField(unique=True)
    case_img = models.TextField()
    total_price = models.PositiveIntegerField(default=0)

class CaseItem(models.Model):
    case = models.ForeignKey(Case, on_delete=models.CASCADE, related_name="items")
    item = models.ForeignKey(Item, on_delete=models.PROTECT)
    percentage = models.PositiveIntegerField(
        validators=[
            MaxValueValidator(100),
            MinValueValidator(1)
        ]
    )

    # ensure that user cant add the same item to the case
    class Meta:
        unique_together = [['case', 'item']]
    
    def save(self, *args, **kwargs):
        self.case.total_price += self.item.price
        self.case.save()
        super().save(*args, **kwargs)

The problem here lies in the total_price field of the Case model. I want that whenever a CaseItem is created and linked to a Case, it should update the total_price field of the Case as well. For instance, if I create a case, case items get added in a new table but I need to update the total_price field of the case as well. Currently, when a case is being created, it is initializing the field by its default value 0. Where am i going wrong?

This is the view for creating a case:

class CreateCustomCase(generics.CreateAPIView):
    serializer_class = CustomCaseSerializer

    def create(self, request, *args, **kwargs):
        data = request.data.copy()
        serializer = self.get_serializer(data=data, context={'request': request})

        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.validated_data, status.HTTP_201_CREATED)

        return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)

and this is the serializer that I am using. Please help. I'm a newbie to django.

class CustomCaseSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=None)
    case_img = serializers.CharField(max_length=None)
    items = CustomCaseItemSerializer(many=True)

    def validate(self, attrs):
        items = attrs.get("items")
        case_name = attrs.get("name")

        try:
            caseObj = Case.objects.get(name=case_name)
        except Case.DoesNotExist:
            caseObj = None

        if caseObj is not None:
            raise serializers.ValidationError("Case with the same alredy exists")

        sumPercentage = sum([item["percentage"] for item in items])

        if sumPercentage != 100:
            raise serializers.ValidationError("Total Sum of percentage should be 100%")

        itemIdList = [item["id"] for item in items]
        selectIds = Item.objects.filter(pk__in=itemIdList).values('id')
        selectIdList = [selectId["id"] for selectId in selectIds]

        if len(selectIdList) != len(itemIdList):
            notInSelect = set(itemIdList).difference(selectIdList)
            raise serializers.ValidationError(
                f'Did not find the following items with id in the database: {notInSelect}'
Back to Top