mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 11:51:10 -05:00
Add migrations for ParkPhoto and RidePhoto models with associated events
- Created ParkPhoto and ParkPhotoEvent models in the parks app, including fields for image, caption, alt text, and relationships to the Park model. - Implemented triggers for insert and update operations on ParkPhoto to log changes in ParkPhotoEvent. - Created RidePhoto and RidePhotoEvent models in the rides app, with similar structure and functionality as ParkPhoto. - Added fields for photo type in RidePhoto and implemented corresponding triggers for logging changes. - Established necessary indexes and unique constraints for both models to ensure data integrity and optimize queries.
This commit is contained in:
@@ -5,8 +5,6 @@ Handles location management for individual rides within parks.
|
||||
|
||||
import requests
|
||||
from typing import List, Dict, Any, Optional, Tuple
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.db import transaction
|
||||
import logging
|
||||
|
||||
@@ -317,7 +315,6 @@ class RideLocationService:
|
||||
ride_location.ride.name.lower() in display_name
|
||||
and park.name.lower() in display_name
|
||||
):
|
||||
|
||||
# Update the ride location
|
||||
ride_location.set_coordinates(
|
||||
float(result["lat"]), float(result["lon"])
|
||||
|
||||
@@ -28,7 +28,7 @@ class RideMediaService:
|
||||
alt_text: str = "",
|
||||
photo_type: str = "exterior",
|
||||
is_primary: bool = False,
|
||||
auto_approve: bool = False
|
||||
auto_approve: bool = False,
|
||||
) -> RidePhoto:
|
||||
"""
|
||||
Upload a photo for a ride.
|
||||
@@ -67,7 +67,7 @@ class RideMediaService:
|
||||
photo_type=photo_type,
|
||||
is_primary=is_primary,
|
||||
is_approved=auto_approve,
|
||||
uploaded_by=user
|
||||
uploaded_by=user,
|
||||
)
|
||||
|
||||
# Extract EXIF date
|
||||
@@ -83,7 +83,7 @@ class RideMediaService:
|
||||
ride: Ride,
|
||||
approved_only: bool = True,
|
||||
primary_first: bool = True,
|
||||
photo_type: Optional[str] = None
|
||||
photo_type: Optional[str] = None,
|
||||
) -> List[RidePhoto]:
|
||||
"""
|
||||
Get photos for a ride.
|
||||
@@ -106,9 +106,9 @@ class RideMediaService:
|
||||
queryset = queryset.filter(photo_type=photo_type)
|
||||
|
||||
if primary_first:
|
||||
queryset = queryset.order_by('-is_primary', '-created_at')
|
||||
queryset = queryset.order_by("-is_primary", "-created_at")
|
||||
else:
|
||||
queryset = queryset.order_by('-created_at')
|
||||
queryset = queryset.order_by("-created_at")
|
||||
|
||||
return list(queryset)
|
||||
|
||||
@@ -141,10 +141,9 @@ class RideMediaService:
|
||||
List of RidePhoto instances
|
||||
"""
|
||||
return list(
|
||||
ride.photos.filter(
|
||||
photo_type=photo_type,
|
||||
is_approved=True
|
||||
).order_by('-created_at')
|
||||
ride.photos.filter(photo_type=photo_type, is_approved=True).order_by(
|
||||
"-created_at"
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -217,7 +216,8 @@ class RideMediaService:
|
||||
photo.delete()
|
||||
|
||||
logger.info(
|
||||
f"Photo {photo_id} deleted from ride {ride_slug} by user {deleted_by.username}")
|
||||
f"Photo {photo_id} deleted from ride {ride_slug} by user {deleted_by.username}"
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to delete photo {photo.pk}: {str(e)}")
|
||||
@@ -238,7 +238,7 @@ class RideMediaService:
|
||||
|
||||
# Get counts by photo type
|
||||
type_counts = {}
|
||||
for photo_type, _ in RidePhoto._meta.get_field('photo_type').choices:
|
||||
for photo_type, _ in RidePhoto._meta.get_field("photo_type").choices:
|
||||
type_counts[photo_type] = photos.filter(photo_type=photo_type).count()
|
||||
|
||||
return {
|
||||
@@ -246,8 +246,8 @@ class RideMediaService:
|
||||
"approved_photos": photos.filter(is_approved=True).count(),
|
||||
"pending_photos": photos.filter(is_approved=False).count(),
|
||||
"has_primary": photos.filter(is_primary=True).exists(),
|
||||
"recent_uploads": photos.order_by('-created_at')[:5].count(),
|
||||
"by_type": type_counts
|
||||
"recent_uploads": photos.order_by("-created_at")[:5].count(),
|
||||
"by_type": type_counts,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -270,7 +270,8 @@ class RideMediaService:
|
||||
approved_count += 1
|
||||
|
||||
logger.info(
|
||||
f"Bulk approved {approved_count} photos by user {approved_by.username}")
|
||||
f"Bulk approved {approved_count} photos by user {approved_by.username}"
|
||||
)
|
||||
return approved_count
|
||||
|
||||
@staticmethod
|
||||
@@ -285,10 +286,9 @@ class RideMediaService:
|
||||
List of construction RidePhoto instances ordered by date taken
|
||||
"""
|
||||
return list(
|
||||
ride.photos.filter(
|
||||
photo_type='construction',
|
||||
is_approved=True
|
||||
).order_by('date_taken', 'created_at')
|
||||
ride.photos.filter(photo_type="construction", is_approved=True).order_by(
|
||||
"date_taken", "created_at"
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -302,4 +302,4 @@ class RideMediaService:
|
||||
Returns:
|
||||
List of on-ride RidePhoto instances
|
||||
"""
|
||||
return RideMediaService.get_photos_by_type(ride, 'onride')
|
||||
return RideMediaService.get_photos_by_type(ride, "onride")
|
||||
|
||||
@@ -12,7 +12,7 @@ from decimal import Decimal
|
||||
from datetime import date
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import Avg, Count, Q, F
|
||||
from django.db.models import Avg, Count, Q
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.rides.models import (
|
||||
|
||||
Reference in New Issue
Block a user