from django.db import models from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from apps.core.history import TrackedModel import pghistory @pghistory.track() class Review(TrackedModel): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="reviews", help_text="User who wrote the review", ) # Generic relation to target object (Park, Ride, etc.) content_type = models.ForeignKey( ContentType, on_delete=models.CASCADE, help_text="Type of item being reviewed", ) object_id = models.PositiveIntegerField(help_text="ID of the item being reviewed") content_object = GenericForeignKey("content_type", "object_id") # Review content rating = models.PositiveSmallIntegerField( choices=[(i, str(i)) for i in range(1, 6)], help_text="Rating from 1 to 5", db_index=True, ) text = models.TextField(blank=True, help_text="Review text (optional)") # Metadata is_public = models.BooleanField( default=True, help_text="Whether this review is visible to others" ) helpful_votes = models.PositiveIntegerField( default=0, help_text="Number of users who found this helpful" ) class Meta(TrackedModel.Meta): verbose_name = "Review" verbose_name_plural = "Reviews" ordering = ["-created_at"] # Ensure one review per user per object unique_together = [["user", "content_type", "object_id"]] indexes = [ models.Index(fields=["content_type", "object_id"]), models.Index(fields=["rating"]), ] def __str__(self): return f"{self.user.username}'s {self.rating}-star review on {self.content_object}"