mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:51:09 -05:00
- Updated ParkDetailOutputSerializer to utilize MediaURLService for generating Cloudflare URLs and friendly URLs for park photos. - Added support for multiple lookup methods (ID and slug) in the park detail endpoint. - Improved documentation for the park detail endpoint, including request properties and response structure. - Created MediaURLService for generating SEO-friendly URLs and handling Cloudflare image URLs. - Comprehensive updates to frontend documentation to reflect new endpoint capabilities and usage examples. - Added detailed park detail endpoint documentation, including request and response structures, field descriptions, and usage examples.
17 KiB
17 KiB
Park Detail Endpoint - Complete Documentation
Endpoint Overview
URL: GET /api/v1/parks/{identifier}/
Description: Retrieve comprehensive park details including location, photos, areas, rides, and company information.
Authentication: None required (public endpoint)
Supports Multiple Lookup Methods:
- By ID:
/api/v1/parks/123/ - By current slug:
/api/v1/parks/cedar-point/ - By historical slug:
/api/v1/parks/old-cedar-point-name/
Request Properties
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
identifier |
string | Yes | Park ID (integer) or slug (string). Supports current and historical slugs. |
Query Parameters
None required - This endpoint returns full park details by default without any query parameters.
Request Headers
| Header | Required | Description |
|---|---|---|
Accept |
No | application/json (default) |
Content-Type |
No | Not applicable for GET requests |
Response Structure
Success Response (200 OK)
{
"id": 1,
"name": "Cedar Point",
"slug": "cedar-point",
"status": "OPERATING",
"description": "America's Roller Coast",
"park_type": "THEME_PARK",
// Dates and Operations
"opening_date": "1870-01-01",
"closing_date": null,
"operating_season": "May - October",
"size_acres": 364.0,
"website": "https://cedarpoint.com",
// Statistics
"average_rating": 4.5,
"coaster_count": 17,
"ride_count": 70,
// Location Information
"location": {
"id": 1,
"latitude": 41.4793,
"longitude": -82.6833,
"street_address": "1 Cedar Point Dr",
"city": "Sandusky",
"state": "Ohio",
"country": "United States",
"continent": "North America",
"postal_code": "44870",
"formatted_address": "1 Cedar Point Dr, Sandusky, OH 44870, United States"
},
// Company Information
"operator": {
"id": 1,
"name": "Cedar Fair",
"slug": "cedar-fair",
"roles": ["OPERATOR"],
"description": "Leading amusement park operator",
"website": "https://cedarfair.com",
"founded_year": 1983
},
"property_owner": {
"id": 1,
"name": "Cedar Fair",
"slug": "cedar-fair",
"roles": ["OPERATOR", "PROPERTY_OWNER"],
"description": "Leading amusement park operator",
"website": "https://cedarfair.com",
"founded_year": 1983
},
// Park Areas/Themed Sections
"areas": [
{
"id": 1,
"name": "Frontier Town",
"slug": "frontier-town",
"description": "Wild West themed area"
},
{
"id": 2,
"name": "Millennium Island",
"slug": "millennium-island",
"description": "Home to Millennium Force"
}
],
// Photo Information
"photos": [
{
"id": 456,
"image_url": "https://imagedelivery.net/account-hash/def789ghi012/public",
"image_variants": {
"thumbnail": "https://imagedelivery.net/account-hash/def789ghi012/thumbnail",
"medium": "https://imagedelivery.net/account-hash/def789ghi012/medium",
"large": "https://imagedelivery.net/account-hash/def789ghi012/large",
"public": "https://imagedelivery.net/account-hash/def789ghi012/public"
},
"friendly_urls": {
"thumbnail": "/parks/cedar-point/photos/beautiful-park-entrance-456-thumbnail.jpg",
"medium": "/parks/cedar-point/photos/beautiful-park-entrance-456-medium.jpg",
"large": "/parks/cedar-point/photos/beautiful-park-entrance-456-large.jpg",
"public": "/parks/cedar-point/photos/beautiful-park-entrance-456.jpg"
},
"caption": "Beautiful park entrance",
"alt_text": "Cedar Point main entrance with flags",
"is_primary": true
}
],
// Primary Photo (designated main photo)
"primary_photo": {
"id": 456,
"image_url": "https://imagedelivery.net/account-hash/def789ghi012/public",
"image_variants": {
"thumbnail": "https://imagedelivery.net/account-hash/def789ghi012/thumbnail",
"medium": "https://imagedelivery.net/account-hash/def789ghi012/medium",
"large": "https://imagedelivery.net/account-hash/def789ghi012/large",
"public": "https://imagedelivery.net/account-hash/def789ghi012/public"
},
"caption": "Beautiful park entrance",
"alt_text": "Cedar Point main entrance with flags"
},
// Banner Image (for hero sections)
"banner_image": {
"id": 456,
"image_url": "https://imagedelivery.net/account-hash/def789ghi012/public",
"image_variants": {
"thumbnail": "https://imagedelivery.net/account-hash/def789ghi012/thumbnail",
"medium": "https://imagedelivery.net/account-hash/def789ghi012/medium",
"large": "https://imagedelivery.net/account-hash/def789ghi012/large",
"public": "https://imagedelivery.net/account-hash/def789ghi012/public"
},
"caption": "Beautiful park entrance",
"alt_text": "Cedar Point main entrance with flags",
"is_fallback": false
},
// Card Image (for listings/cards)
"card_image": {
"id": 456,
"image_url": "https://imagedelivery.net/account-hash/def789ghi012/public",
"image_variants": {
"thumbnail": "https://imagedelivery.net/account-hash/def789ghi012/thumbnail",
"medium": "https://imagedelivery.net/account-hash/def789ghi012/medium",
"large": "https://imagedelivery.net/account-hash/def789ghi012/large",
"public": "https://imagedelivery.net/account-hash/def789ghi012/public"
},
"caption": "Beautiful park entrance",
"alt_text": "Cedar Point main entrance with flags",
"is_fallback": false
},
// Frontend URL
"url": "https://thrillwiki.com/parks/cedar-point/",
// Metadata
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T12:30:00Z"
}
Error Responses
404 Not Found
{
"detail": "Park not found"
}
500 Internal Server Error
{
"detail": "Internal server error"
}
Field Descriptions
Core Park Information
| Field | Type | Description |
|---|---|---|
id |
integer | Unique park identifier |
name |
string | Official park name |
slug |
string | URL-friendly identifier |
status |
string | Operational status (see Status Values) |
description |
string | Park description/tagline |
park_type |
string | Park category (see Park Type Values) |
Operational Details
| Field | Type | Description |
|---|---|---|
opening_date |
date | Park opening date (YYYY-MM-DD) |
closing_date |
date | Park closing date (null if still operating) |
operating_season |
string | Seasonal operation description |
size_acres |
decimal | Park size in acres |
website |
string | Official park website URL |
Statistics
| Field | Type | Description |
|---|---|---|
average_rating |
decimal | Average user rating (1-10 scale) |
coaster_count |
integer | Number of roller coasters |
ride_count |
integer | Total number of rides |
Location Object
| Field | Type | Description |
|---|---|---|
id |
integer | Location record ID |
latitude |
float | Geographic latitude |
longitude |
float | Geographic longitude |
street_address |
string | Street address |
city |
string | City name |
state |
string | State/province |
country |
string | Country name |
continent |
string | Continent name |
postal_code |
string | ZIP/postal code |
formatted_address |
string | Complete formatted address |
Company Objects (Operator/Property Owner)
| Field | Type | Description |
|---|---|---|
id |
integer | Company ID |
name |
string | Company name |
slug |
string | URL-friendly identifier |
roles |
array | Company roles (OPERATOR, PROPERTY_OWNER, etc.) |
description |
string | Company description |
website |
string | Company website |
founded_year |
integer | Year company was founded |
Area Objects
| Field | Type | Description |
|---|---|---|
id |
integer | Area ID |
name |
string | Area/section name |
slug |
string | URL-friendly identifier |
description |
string | Area description |
Photo Objects
| Field | Type | Description |
|---|---|---|
id |
integer | Photo ID |
image_url |
string | Base Cloudflare image URL |
image_variants |
object | Available image sizes/transformations |
caption |
string | Photo caption |
alt_text |
string | Accessibility alt text |
is_primary |
boolean | Whether this is the primary photo |
is_fallback |
boolean | Whether this is a fallback image |
Image Variants Object
| Field | Type | Description |
|---|---|---|
thumbnail |
string | Small thumbnail URL (150x150) |
medium |
string | Medium size URL (500x500) |
large |
string | Large size URL (1200x1200) |
public |
string | Full size public URL |
Enumerated Values
Status Values
| Value | Description |
|---|---|
OPERATING |
Currently operating |
CLOSED_TEMP |
Temporarily closed |
CLOSED_PERM |
Permanently closed |
UNDER_CONSTRUCTION |
Under construction |
DEMOLISHED |
Demolished |
RELOCATED |
Relocated |
Park Type Values
| Value | Description |
|---|---|
THEME_PARK |
Theme park |
AMUSEMENT_PARK |
Amusement park |
WATER_PARK |
Water park |
FAMILY_ENTERTAINMENT_CENTER |
Family entertainment center |
CARNIVAL |
Carnival |
FAIR |
Fair |
PIER |
Pier |
BOARDWALK |
Boardwalk |
SAFARI_PARK |
Safari park |
ZOO |
Zoo |
OTHER |
Other |
Usage Examples
JavaScript/TypeScript
// Fetch by ID
const parkById = await fetch('/api/v1/parks/123/');
const parkData = await parkById.json();
// Fetch by current slug
const parkBySlug = await fetch('/api/v1/parks/cedar-point/');
const parkData2 = await parkBySlug.json();
// Fetch by historical slug
const parkByHistoricalSlug = await fetch('/api/v1/parks/old-name/');
const parkData3 = await parkByHistoricalSlug.json();
// Access different image sizes
const thumbnailUrl = parkData.primary_photo?.image_variants.thumbnail;
const fullSizeUrl = parkData.primary_photo?.image_variants.public;
Python
import requests
# Fetch park details
response = requests.get('https://api.thrillwiki.com/api/v1/parks/cedar-point/')
park_data = response.json()
# Access park information
park_name = park_data['name']
location = park_data['location']
operator = park_data['operator']
photos = park_data['photos']
cURL
# Fetch by slug
curl -X GET "https://api.thrillwiki.com/api/v1/parks/cedar-point/" \
-H "Accept: application/json"
# Fetch by ID
curl -X GET "https://api.thrillwiki.com/api/v1/parks/123/" \
-H "Accept: application/json"
Related Endpoints
- Park List:
GET /api/v1/parks/- List parks with filtering - Park Photos:
GET /api/v1/parks/{id}/photos/- Manage park photos - Park Areas:
GET /api/v1/parks/{id}/areas/- Park themed areas - Park Image Settings:
PATCH /api/v1/parks/{id}/image-settings/- Set banner/card images
Photo Handling Details
Photo Upload vs Display Distinction
Important: You can upload unlimited photos per park, but the park detail endpoint shows only the 10 most relevant photos for performance optimization.
Photo Upload Capacity
- No Upload Limit: Upload unlimited photos per park via
POST /api/v1/parks/{park_id}/photos/ - Storage: All photos stored in database and Cloudflare Images
- Approval System: Each photo goes through moderation (
is_approvedfield) - Photo Types: Categorize photos (banner, card, gallery, etc.)
- Bulk Upload: Support for multiple photo uploads
Display Limit (Detail Endpoint)
- 10 Photo Limit: Only applies to this park detail endpoint response
- Smart Selection: Shows 10 most relevant photos using intelligent ordering:
- Primary photos first (
-is_primary) - Newest photos next (
-created_at) - Only approved photos (
is_approved=True)
- Primary photos first (
Complete Photo Access
All Photos Available Via Dedicated Endpoint
GET /api/v1/parks/{park_id}/photos/
- No Limit: Returns all uploaded photos for the park
- Pagination: Supports pagination for large photo collections
- Filtering: Filter by photo type, approval status, etc.
- Full Management: Complete CRUD operations for all photos
Photo URL Structure Per Park
Maximum Possible URLs per park:
- General photos: 10 photos × 4 variants = 40 URLs
- Primary photo: 1 photo × 4 variants = 4 URLs
- Banner image: 1 photo × 4 variants = 4 URLs
- Card image: 1 photo × 4 variants = 4 URLs
- Total Maximum: 52 photo URLs per park
Each photo includes 4 Cloudflare transformation URLs:
thumbnail: Optimized for small previews (150x150)medium: Medium resolution for general use (500x500)large: High resolution for detailed viewing (1200x1200)public: Original/full size image
Practical Example
A park could have:
- 50 uploaded photos (all stored in system)
- 30 approved photos (available for public display)
- 10 photos shown in park detail endpoint (most relevant)
- All 30 approved photos accessible via
/api/v1/parks/{id}/photos/
Frontend Implementation Strategy
// Get park with essential photos (fast initial load)
const park = await fetch('/api/v1/parks/cedar-point/');
// Get complete photo gallery when needed (e.g., photo gallery page)
const allPhotos = await fetch('/api/v1/parks/123/photos/?page_size=50');
Friendly URLs for Photos
NEW FEATURE: Each photo now includes both Cloudflare URLs and SEO-friendly URLs.
URL Structure
/parks/{park-slug}/photos/{caption-slug}-{photo-id}-{variant}.jpg
Examples:
/parks/cedar-point/photos/beautiful-park-entrance-456.jpg(public/original)/parks/cedar-point/photos/beautiful-park-entrance-456-thumbnail.jpg/parks/cedar-point/photos/beautiful-park-entrance-456-medium.jpg/parks/cedar-point/photos/beautiful-park-entrance-456-large.jpg
Benefits
- SEO Optimized: Descriptive URLs improve search engine ranking
- User Friendly: URLs are readable and meaningful
- Consistent: Follows predictable pattern across all photos
- Backwards Compatible: Original Cloudflare URLs still available
Implementation
Each photo object now includes both URL types:
{
"id": 456,
"image_url": "https://imagedelivery.net/account-hash/def789ghi012/public",
"image_variants": {
"thumbnail": "https://imagedelivery.net/account-hash/def789ghi012/thumbnail",
"medium": "https://imagedelivery.net/account-hash/def789ghi012/medium",
"large": "https://imagedelivery.net/account-hash/def789ghi012/large",
"public": "https://imagedelivery.net/account-hash/def789ghi012/public"
},
"friendly_urls": {
"thumbnail": "/parks/cedar-point/photos/beautiful-park-entrance-456-thumbnail.jpg",
"medium": "/parks/cedar-point/photos/beautiful-park-entrance-456-medium.jpg",
"large": "/parks/cedar-point/photos/beautiful-park-entrance-456-large.jpg",
"public": "/parks/cedar-point/photos/beautiful-park-entrance-456.jpg"
},
"caption": "Beautiful park entrance",
"alt_text": "Cedar Point main entrance with flags"
}
Photo Management Features
- Primary Photo: Designate which photo represents the park
- Banner/Card Images: Set specific photos for different UI contexts
- Fallback Logic: Banner and card images automatically fallback to latest approved photo if not explicitly set
- Approval Workflow: Moderate photos before public display
- Photo Metadata: Each photo includes caption, alt text, and categorization
- Dual URL System: Both Cloudflare and friendly URLs provided for maximum flexibility
Performance Notes
- Response includes optimized database queries with
select_relatedandprefetch_related - Photos limited to 10 most recent approved photos for optimal response size
- Image variants are pre-computed Cloudflare transformations for fast delivery
- Historical slug lookup may require additional database queries
- Smart photo selection ensures most relevant photos are included
Caching
- No caching implemented at endpoint level
- Cloudflare images are cached at CDN level
- Consider implementing Redis caching for frequently accessed parks
Rate Limiting
- No rate limiting currently implemented
- Public endpoint accessible without authentication
- Consider implementing rate limiting for production use