Refactor code structure and remove redundant changes

This commit is contained in:
pacnpal
2025-11-09 16:31:34 -05:00
parent 2884bc23ce
commit eb68cf40c6
1080 changed files with 27361 additions and 56687 deletions

View File

@@ -0,0 +1,202 @@
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from model_utils.models import TimeStampedModel
import pghistory
@pghistory.track()
class Review(TimeStampedModel):
"""
User reviews for parks or rides.
Users can leave reviews with ratings, text, photos, and metadata like visit date.
Reviews support helpful voting and go through moderation workflow.
"""
# User who created the review
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='reviews'
)
# Generic relation - can review either a Park or a Ride
content_type = models.ForeignKey(
ContentType,
on_delete=models.CASCADE,
limit_choices_to={'model__in': ('park', 'ride')}
)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
# Review content
title = models.CharField(max_length=200)
content = models.TextField()
rating = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(5)],
help_text="Rating from 1 to 5 stars"
)
# Visit metadata
visit_date = models.DateField(
null=True,
blank=True,
help_text="Date the user visited"
)
wait_time_minutes = models.PositiveIntegerField(
null=True,
blank=True,
help_text="Wait time in minutes"
)
# Helpful voting system
helpful_votes = models.PositiveIntegerField(
default=0,
help_text="Number of users who found this review helpful"
)
total_votes = models.PositiveIntegerField(
default=0,
help_text="Total number of votes (helpful + not helpful)"
)
# Moderation status
MODERATION_PENDING = 'pending'
MODERATION_APPROVED = 'approved'
MODERATION_REJECTED = 'rejected'
MODERATION_STATUS_CHOICES = [
(MODERATION_PENDING, 'Pending'),
(MODERATION_APPROVED, 'Approved'),
(MODERATION_REJECTED, 'Rejected'),
]
moderation_status = models.CharField(
max_length=20,
choices=MODERATION_STATUS_CHOICES,
default=MODERATION_PENDING,
db_index=True
)
moderation_notes = models.TextField(
blank=True,
help_text="Notes from moderator"
)
moderated_at = models.DateTimeField(null=True, blank=True)
moderated_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='moderated_reviews'
)
# Link to ContentSubmission (Sacred Pipeline integration)
submission = models.ForeignKey(
'moderation.ContentSubmission',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='reviews',
help_text="ContentSubmission that created this review"
)
# Photos related to this review (via media.Photo model with generic relation)
photos = GenericRelation('media.Photo')
class Meta:
ordering = ['-created']
indexes = [
models.Index(fields=['content_type', 'object_id']),
models.Index(fields=['user', 'created']),
models.Index(fields=['moderation_status', 'created']),
models.Index(fields=['rating']),
]
# A user can only review a specific park/ride once
unique_together = [['user', 'content_type', 'object_id']]
def __str__(self):
entity_type = self.content_type.model
return f"{self.user.username}'s review of {entity_type} #{self.object_id}"
@property
def helpful_percentage(self):
"""Calculate percentage of helpful votes."""
if self.total_votes == 0:
return None
return (self.helpful_votes / self.total_votes) * 100
@property
def is_approved(self):
"""Check if review is approved."""
return self.moderation_status == self.MODERATION_APPROVED
@property
def is_pending(self):
"""Check if review is pending moderation."""
return self.moderation_status == self.MODERATION_PENDING
class ReviewHelpfulVote(TimeStampedModel):
"""
Track individual helpful votes to prevent duplicate voting.
"""
review = models.ForeignKey(
Review,
on_delete=models.CASCADE,
related_name='vote_records'
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='review_votes'
)
is_helpful = models.BooleanField(
help_text="True if user found review helpful, False if not helpful"
)
class Meta:
unique_together = [['review', 'user']]
indexes = [
models.Index(fields=['review', 'user']),
]
def __str__(self):
vote_type = "helpful" if self.is_helpful else "not helpful"
return f"{self.user.username} voted {vote_type} on review #{self.review.id}"
def save(self, *args, **kwargs):
"""Update review vote counts when saving."""
is_new = self.pk is None
old_is_helpful = None
if not is_new:
# Get old value before update
old_vote = ReviewHelpfulVote.objects.get(pk=self.pk)
old_is_helpful = old_vote.is_helpful
super().save(*args, **kwargs)
# Update review vote counts
if is_new:
# New vote
self.review.total_votes += 1
if self.is_helpful:
self.review.helpful_votes += 1
self.review.save()
elif old_is_helpful != self.is_helpful:
# Vote changed
if self.is_helpful:
self.review.helpful_votes += 1
else:
self.review.helpful_votes -= 1
self.review.save()
def delete(self, *args, **kwargs):
"""Update review vote counts when deleting."""
self.review.total_votes -= 1
if self.is_helpful:
self.review.helpful_votes -= 1
self.review.save()
super().delete(*args, **kwargs)