from django.db.models.signals import post_save, post_delete from django.dispatch import receiver from django.db.models import Avg from .models import Review @receiver(post_save, sender=Review) @receiver(post_delete, sender=Review) def update_average_rating(sender, instance, **kwargs): """ Update the average rating of the content object when a review is saved or deleted. """ content_object = instance.content_object if not content_object: # If content object doesn't exist (orphaned review?), skip return # Check if the content object has an 'average_rating' field if not hasattr(content_object, 'average_rating'): return # Calculate new average # We query the Review model filtering by content_type and object_id avg_rating = Review.objects.filter( content_type=instance.content_type, object_id=instance.object_id ).aggregate(Avg('rating'))['rating__avg'] # Update field content_object.average_rating = avg_rating or 0 # Default to 0 if no reviews content_object.save(update_fields=['average_rating'])