mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:11:13 -05:00
Add email templates for user notifications and account management
- Created a base email template (base.html) for consistent styling across all emails. - Added moderation approval email template (moderation_approved.html) to notify users of approved submissions. - Added moderation rejection email template (moderation_rejected.html) to inform users of required changes for their submissions. - Created password reset email template (password_reset.html) for users requesting to reset their passwords. - Developed a welcome email template (welcome.html) to greet new users and provide account details and tips for using ThrillWiki.
This commit is contained in:
247
django/api/v1/endpoints/ride_models.py
Normal file
247
django/api/v1/endpoints/ride_models.py
Normal file
@@ -0,0 +1,247 @@
|
||||
"""
|
||||
Ride Model endpoints for API v1.
|
||||
|
||||
Provides CRUD operations for RideModel entities with filtering and search.
|
||||
"""
|
||||
from typing import List, Optional
|
||||
from uuid import UUID
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.db.models import Q
|
||||
from ninja import Router, Query
|
||||
from ninja.pagination import paginate, PageNumberPagination
|
||||
|
||||
from apps.entities.models import RideModel, Company
|
||||
from ..schemas import (
|
||||
RideModelCreate,
|
||||
RideModelUpdate,
|
||||
RideModelOut,
|
||||
RideModelListOut,
|
||||
ErrorResponse
|
||||
)
|
||||
|
||||
|
||||
router = Router(tags=["Ride Models"])
|
||||
|
||||
|
||||
class RideModelPagination(PageNumberPagination):
|
||||
"""Custom pagination for ride models."""
|
||||
page_size = 50
|
||||
|
||||
|
||||
@router.get(
|
||||
"/",
|
||||
response={200: List[RideModelOut]},
|
||||
summary="List ride models",
|
||||
description="Get a paginated list of ride models with optional filtering"
|
||||
)
|
||||
@paginate(RideModelPagination)
|
||||
def list_ride_models(
|
||||
request,
|
||||
search: Optional[str] = Query(None, description="Search by model name"),
|
||||
manufacturer_id: Optional[UUID] = Query(None, description="Filter by manufacturer"),
|
||||
model_type: Optional[str] = Query(None, description="Filter by model type"),
|
||||
ordering: Optional[str] = Query("-created", description="Sort by field (prefix with - for descending)")
|
||||
):
|
||||
"""
|
||||
List all ride models with optional filters.
|
||||
|
||||
**Filters:**
|
||||
- search: Search model names (case-insensitive partial match)
|
||||
- manufacturer_id: Filter by manufacturer
|
||||
- model_type: Filter by model type
|
||||
- ordering: Sort results (default: -created)
|
||||
|
||||
**Returns:** Paginated list of ride models
|
||||
"""
|
||||
queryset = RideModel.objects.select_related('manufacturer').all()
|
||||
|
||||
# Apply search filter
|
||||
if search:
|
||||
queryset = queryset.filter(
|
||||
Q(name__icontains=search) | Q(description__icontains=search)
|
||||
)
|
||||
|
||||
# Apply manufacturer filter
|
||||
if manufacturer_id:
|
||||
queryset = queryset.filter(manufacturer_id=manufacturer_id)
|
||||
|
||||
# Apply model type filter
|
||||
if model_type:
|
||||
queryset = queryset.filter(model_type=model_type)
|
||||
|
||||
# Apply ordering
|
||||
valid_order_fields = ['name', 'created', 'modified', 'installation_count']
|
||||
order_field = ordering.lstrip('-')
|
||||
if order_field in valid_order_fields:
|
||||
queryset = queryset.order_by(ordering)
|
||||
else:
|
||||
queryset = queryset.order_by('-created')
|
||||
|
||||
# Annotate with manufacturer name
|
||||
for model in queryset:
|
||||
model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{model_id}",
|
||||
response={200: RideModelOut, 404: ErrorResponse},
|
||||
summary="Get ride model",
|
||||
description="Retrieve a single ride model by ID"
|
||||
)
|
||||
def get_ride_model(request, model_id: UUID):
|
||||
"""
|
||||
Get a ride model by ID.
|
||||
|
||||
**Parameters:**
|
||||
- model_id: UUID of the ride model
|
||||
|
||||
**Returns:** Ride model details
|
||||
"""
|
||||
model = get_object_or_404(RideModel.objects.select_related('manufacturer'), id=model_id)
|
||||
model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
|
||||
return model
|
||||
|
||||
|
||||
@router.post(
|
||||
"/",
|
||||
response={201: RideModelOut, 400: ErrorResponse, 404: ErrorResponse},
|
||||
summary="Create ride model",
|
||||
description="Create a new ride model (requires authentication)"
|
||||
)
|
||||
def create_ride_model(request, payload: RideModelCreate):
|
||||
"""
|
||||
Create a new ride model.
|
||||
|
||||
**Authentication:** Required
|
||||
|
||||
**Parameters:**
|
||||
- payload: Ride model data
|
||||
|
||||
**Returns:** Created ride model
|
||||
"""
|
||||
# TODO: Add authentication check
|
||||
# if not request.auth:
|
||||
# return 401, {"detail": "Authentication required"}
|
||||
|
||||
# Verify manufacturer exists
|
||||
manufacturer = get_object_or_404(Company, id=payload.manufacturer_id)
|
||||
|
||||
model = RideModel.objects.create(**payload.dict())
|
||||
model.manufacturer_name = manufacturer.name
|
||||
return 201, model
|
||||
|
||||
|
||||
@router.put(
|
||||
"/{model_id}",
|
||||
response={200: RideModelOut, 404: ErrorResponse, 400: ErrorResponse},
|
||||
summary="Update ride model",
|
||||
description="Update an existing ride model (requires authentication)"
|
||||
)
|
||||
def update_ride_model(request, model_id: UUID, payload: RideModelUpdate):
|
||||
"""
|
||||
Update a ride model.
|
||||
|
||||
**Authentication:** Required
|
||||
|
||||
**Parameters:**
|
||||
- model_id: UUID of the ride model
|
||||
- payload: Updated ride model data
|
||||
|
||||
**Returns:** Updated ride model
|
||||
"""
|
||||
# TODO: Add authentication check
|
||||
# if not request.auth:
|
||||
# return 401, {"detail": "Authentication required"}
|
||||
|
||||
model = get_object_or_404(RideModel.objects.select_related('manufacturer'), id=model_id)
|
||||
|
||||
# Update only provided fields
|
||||
for key, value in payload.dict(exclude_unset=True).items():
|
||||
setattr(model, key, value)
|
||||
|
||||
model.save()
|
||||
model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
|
||||
return model
|
||||
|
||||
|
||||
@router.patch(
|
||||
"/{model_id}",
|
||||
response={200: RideModelOut, 404: ErrorResponse, 400: ErrorResponse},
|
||||
summary="Partial update ride model",
|
||||
description="Partially update an existing ride model (requires authentication)"
|
||||
)
|
||||
def partial_update_ride_model(request, model_id: UUID, payload: RideModelUpdate):
|
||||
"""
|
||||
Partially update a ride model.
|
||||
|
||||
**Authentication:** Required
|
||||
|
||||
**Parameters:**
|
||||
- model_id: UUID of the ride model
|
||||
- payload: Fields to update
|
||||
|
||||
**Returns:** Updated ride model
|
||||
"""
|
||||
# TODO: Add authentication check
|
||||
# if not request.auth:
|
||||
# return 401, {"detail": "Authentication required"}
|
||||
|
||||
model = get_object_or_404(RideModel.objects.select_related('manufacturer'), id=model_id)
|
||||
|
||||
# Update only provided fields
|
||||
for key, value in payload.dict(exclude_unset=True).items():
|
||||
setattr(model, key, value)
|
||||
|
||||
model.save()
|
||||
model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
|
||||
return model
|
||||
|
||||
|
||||
@router.delete(
|
||||
"/{model_id}",
|
||||
response={204: None, 404: ErrorResponse},
|
||||
summary="Delete ride model",
|
||||
description="Delete a ride model (requires authentication)"
|
||||
)
|
||||
def delete_ride_model(request, model_id: UUID):
|
||||
"""
|
||||
Delete a ride model.
|
||||
|
||||
**Authentication:** Required
|
||||
|
||||
**Parameters:**
|
||||
- model_id: UUID of the ride model
|
||||
|
||||
**Returns:** No content (204)
|
||||
"""
|
||||
# TODO: Add authentication check
|
||||
# if not request.auth:
|
||||
# return 401, {"detail": "Authentication required"}
|
||||
|
||||
model = get_object_or_404(RideModel, id=model_id)
|
||||
model.delete()
|
||||
return 204, None
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{model_id}/installations",
|
||||
response={200: List[dict], 404: ErrorResponse},
|
||||
summary="Get ride model installations",
|
||||
description="Get all ride installations of this model"
|
||||
)
|
||||
def get_ride_model_installations(request, model_id: UUID):
|
||||
"""
|
||||
Get all installations of a ride model.
|
||||
|
||||
**Parameters:**
|
||||
- model_id: UUID of the ride model
|
||||
|
||||
**Returns:** List of rides using this model
|
||||
"""
|
||||
model = get_object_or_404(RideModel, id=model_id)
|
||||
rides = model.rides.select_related('park').all().values(
|
||||
'id', 'name', 'slug', 'status', 'park__name', 'park__id'
|
||||
)
|
||||
return list(rides)
|
||||
Reference in New Issue
Block a user