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:
pacnpal
2025-08-26 14:40:46 -04:00
parent 831be6a2ee
commit e4e36c7899
133 changed files with 1321 additions and 1001 deletions

View File

@@ -12,15 +12,9 @@ from drf_spectacular.utils import (
OpenApiExample,
)
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError as DjangoValidationError
from django.utils.crypto import get_random_string
from django.utils import timezone
from datetime import timedelta
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.contrib.auth import get_user_model
from apps.accounts.models import UserProfile, TopList, TopListItem
UserModel = get_user_model()
@@ -44,6 +38,7 @@ class ModelChoices:
# === AUTHENTICATION SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(
@@ -298,6 +293,7 @@ class AuthStatusOutputSerializer(serializers.Serializer):
# === USER PROFILE SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(
@@ -388,6 +384,7 @@ class UserProfileUpdateInputSerializer(serializers.Serializer):
# === TOP LIST SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(
@@ -447,6 +444,7 @@ class TopListUpdateInputSerializer(serializers.Serializer):
# === TOP LIST ITEM SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(

View File

@@ -21,13 +21,22 @@ urlpatterns = [
path("signup/", views.SignupAPIView.as_view(), name="auth-signup"),
path("logout/", views.LogoutAPIView.as_view(), name="auth-logout"),
path("user/", views.CurrentUserAPIView.as_view(), name="auth-current-user"),
path("password/reset/", views.PasswordResetAPIView.as_view(), name="auth-password-reset"),
path("password/change/", views.PasswordChangeAPIView.as_view(),
name="auth-password-change"),
path("social/providers/", views.SocialProvidersAPIView.as_view(),
name="auth-social-providers"),
path(
"password/reset/",
views.PasswordResetAPIView.as_view(),
name="auth-password-reset",
),
path(
"password/change/",
views.PasswordChangeAPIView.as_view(),
name="auth-password-change",
),
path(
"social/providers/",
views.SocialProvidersAPIView.as_view(),
name="auth-social-providers",
),
path("status/", views.AuthStatusAPIView.as_view(), name="auth-status"),
# Include router URLs for ViewSets (profiles, top lists)
path("", include(router.urls)),
]

View File

@@ -6,12 +6,9 @@ login, signup, logout, password management, social authentication,
user profiles, and top lists.
"""
import time
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.conf import settings
from django.db.models import Q
from rest_framework import status
from rest_framework.views import APIView
@@ -20,7 +17,6 @@ from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.decorators import action
from allauth.socialaccount import providers
from drf_spectacular.utils import extend_schema, extend_schema_view
from apps.accounts.models import UserProfile, TopList, TopListItem
@@ -72,6 +68,7 @@ UserModel = get_user_model()
# === AUTHENTICATION API VIEWS ===
@extend_schema_view(
post=extend_schema(
summary="User login",
@@ -250,7 +247,7 @@ class LogoutAPIView(APIView):
{"message": "Logout successful"}
)
return Response(response_serializer.data)
except Exception as e:
except Exception:
return Response(
{"error": "Logout failed"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
@@ -361,7 +358,6 @@ class SocialProvidersAPIView(APIView):
def get(self, request: Request) -> Response:
from django.core.cache import cache
from django.contrib.sites.shortcuts import get_current_site
site = get_current_site(request._request) # type: ignore[attr-defined]
@@ -446,6 +442,7 @@ class AuthStatusAPIView(APIView):
# === USER PROFILE API VIEWS ===
class UserProfileViewSet(ModelViewSet):
"""ViewSet for managing user profiles."""
@@ -481,6 +478,7 @@ class UserProfileViewSet(ModelViewSet):
# === TOP LIST API VIEWS ===
class TopListViewSet(ModelViewSet):
"""ViewSet for managing user top lists."""