mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 05:31:09 -05:00
Add comprehensive API documentation for ThrillWiki integration and features
- Introduced Next.js integration guide for ThrillWiki API, detailing authentication, core domain APIs, data structures, and implementation patterns. - Documented the migration to Rich Choice Objects, highlighting changes for frontend developers and enhanced metadata availability. - Fixed the missing `get_by_slug` method in the Ride model, ensuring proper functionality of ride detail endpoints. - Created a test script to verify manufacturer syncing with ride models, ensuring data integrity across related models.
This commit is contained in:
@@ -1,510 +1,187 @@
|
||||
# Park Detail Endpoint - Complete Documentation
|
||||
# Park Detail Endpoints Documentation
|
||||
|
||||
## Endpoint Overview
|
||||
## Overview
|
||||
|
||||
**URL:** `GET /api/v1/parks/{identifier}/`
|
||||
The ThrillWiki API provides multiple endpoints for accessing park information with different levels of detail and functionality.
|
||||
|
||||
**Description:** Retrieve comprehensive park details including location, photos, areas, rides, and company information.
|
||||
## Available Endpoints
|
||||
|
||||
**Authentication:** None required (public endpoint)
|
||||
### 1. Basic Park Detail
|
||||
**Endpoint:** `GET /api/v1/parks/{park-slug}/`
|
||||
**Purpose:** Fast loading of core park information
|
||||
|
||||
**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/`
|
||||
**Response includes:**
|
||||
- Basic park details (name, slug, status, description)
|
||||
- Location information with coordinates
|
||||
- Operator and property owner details
|
||||
- Park statistics (ride count, coaster count, average rating)
|
||||
- Park areas/themed sections
|
||||
- Photo information (primary, banner, card images)
|
||||
- **Does NOT include individual ride details**
|
||||
|
||||
## Request Properties
|
||||
### 2. Park Rides List (Paginated)
|
||||
**Endpoint:** `GET /api/v1/parks/{park-slug}/rides/`
|
||||
**Purpose:** Paginated list of all rides at a specific park
|
||||
|
||||
### Path Parameters
|
||||
**Query Parameters:**
|
||||
- `page` - Page number for pagination
|
||||
- `page_size` - Number of results per page (max 100, default 20)
|
||||
- `category` - Filter by ride category (RC, FR, WR, etc.)
|
||||
- `status` - Filter by operational status
|
||||
- `search` - Search rides by name or description
|
||||
- `ordering` - Order results by field
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `identifier` | string | Yes | Park ID (integer) or slug (string). Supports current and historical slugs. |
|
||||
**Response includes:**
|
||||
- Paginated list of rides with full details
|
||||
- Each ride includes: name, slug, category, status, manufacturer, ratings, capacity, dates
|
||||
- Pagination metadata (count, next, previous)
|
||||
|
||||
### Query Parameters
|
||||
### 3. Individual Park Ride Detail
|
||||
**Endpoint:** `GET /api/v1/parks/{park-slug}/rides/{ride-slug}/`
|
||||
**Purpose:** Comprehensive details for a specific ride within park context
|
||||
|
||||
**None required** - This endpoint returns full park details by default without any query parameters.
|
||||
**Response includes:**
|
||||
- Complete ride information
|
||||
- Park context information
|
||||
- Manufacturer and designer details
|
||||
- Technical specifications
|
||||
- Photos and media
|
||||
|
||||
### Request Headers
|
||||
### 4. Comprehensive Park Detail (RESTORED)
|
||||
**Endpoint:** `GET /api/v1/parks/{park-slug}/detail/`
|
||||
**Purpose:** Complete park information with rides summary
|
||||
|
||||
| Header | Required | Description |
|
||||
|--------|----------|-------------|
|
||||
| `Accept` | No | `application/json` (default) |
|
||||
| `Content-Type` | No | Not applicable for GET requests |
|
||||
|
||||
## Response Structure
|
||||
|
||||
### Success Response (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
```json
|
||||
{
|
||||
"detail": "Park not found"
|
||||
}
|
||||
```
|
||||
|
||||
#### 500 Internal Server Error
|
||||
```json
|
||||
{
|
||||
"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 |
|
||||
**Response includes:**
|
||||
- All basic park detail information
|
||||
- **Plus:** `rides_summary` object containing:
|
||||
- `total_count` - Total number of rides at the park
|
||||
- `sample` - First 10 rides with full details
|
||||
- `full_list_url` - Link to paginated rides endpoint
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### JavaScript/TypeScript
|
||||
|
||||
```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
|
||||
|
||||
```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
|
||||
|
||||
### Basic Park Info (Fast Loading)
|
||||
```bash
|
||||
# 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"
|
||||
curl "http://localhost:8000/api/v1/parks/cedar-point/"
|
||||
```
|
||||
|
||||
## Related Endpoints
|
||||
### All Rides at Park (Paginated)
|
||||
```bash
|
||||
# First page
|
||||
curl "http://localhost:8000/api/v1/parks/cedar-point/rides/"
|
||||
|
||||
- **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
|
||||
# With filtering
|
||||
curl "http://localhost:8000/api/v1/parks/cedar-point/rides/?category=RC&status=OPERATING"
|
||||
|
||||
## 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_approved` field)
|
||||
- **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:
|
||||
1. **Primary photos first** (`-is_primary`)
|
||||
2. **Newest photos next** (`-created_at`)
|
||||
3. **Only approved photos** (`is_approved=True`)
|
||||
|
||||
### 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:**
|
||||
1. **`thumbnail`**: Optimized for small previews (150x150)
|
||||
2. **`medium`**: Medium resolution for general use (500x500)
|
||||
3. **`large`**: High resolution for detailed viewing (1200x1200)
|
||||
4. **`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**
|
||||
```javascript
|
||||
// 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');
|
||||
# With pagination
|
||||
curl "http://localhost:8000/api/v1/parks/cedar-point/rides/?page=2&page_size=10"
|
||||
```
|
||||
|
||||
### 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
|
||||
### Comprehensive Park Detail (With Rides Summary)
|
||||
```bash
|
||||
curl "http://localhost:8000/api/v1/parks/cedar-point/detail/"
|
||||
```
|
||||
|
||||
**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`
|
||||
### Specific Ride at Park
|
||||
```bash
|
||||
curl "http://localhost:8000/api/v1/parks/cedar-point/rides/millennium-force/"
|
||||
```
|
||||
|
||||
#### **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
|
||||
## Frontend Implementation Strategy
|
||||
|
||||
#### **Implementation**
|
||||
Each photo object now includes both URL types:
|
||||
### Recommended Approach
|
||||
1. **Initial Page Load:** Use `/parks/{slug}/` for fast park header/info
|
||||
2. **Progressive Enhancement:** Load rides via `/parks/{slug}/rides/` with pagination
|
||||
3. **Alternative:** Use `/parks/{slug}/detail/` for single-request comprehensive data
|
||||
|
||||
### Performance Considerations
|
||||
- Basic park detail: ~2KB response, very fast
|
||||
- Rides list: ~20KB per page (20 rides), paginated
|
||||
- Comprehensive detail: ~25KB response, includes rides sample
|
||||
|
||||
### Caching Strategy
|
||||
- Basic park data: Long cache (park info changes rarely)
|
||||
- Rides data: Medium cache (ride status may change)
|
||||
- Comprehensive detail: Medium cache (combines both)
|
||||
|
||||
## Response Structure Examples
|
||||
|
||||
### Basic Park Detail Response
|
||||
```json
|
||||
{
|
||||
"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"
|
||||
"id": 249,
|
||||
"name": "Cedar Point",
|
||||
"slug": "cedar-point",
|
||||
"status": "OPERATING",
|
||||
"description": "Roller coaster capital of the world",
|
||||
"location": {
|
||||
"city": "Sandusky",
|
||||
"state": "OH",
|
||||
"country": "USA",
|
||||
"latitude": 41.4814,
|
||||
"longitude": -82.6838
|
||||
},
|
||||
"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"
|
||||
"operator": {
|
||||
"id": 339,
|
||||
"name": "Cedar Fair",
|
||||
"slug": "cedar-fair"
|
||||
},
|
||||
"caption": "Beautiful park entrance",
|
||||
"alt_text": "Cedar Point main entrance with flags"
|
||||
"ride_count": 4,
|
||||
"coaster_count": 0,
|
||||
"average_rating": "8.16"
|
||||
}
|
||||
```
|
||||
|
||||
### Photo Management Features
|
||||
### Comprehensive Detail Response (Additional Fields)
|
||||
```json
|
||||
{
|
||||
// ... all basic park fields ...
|
||||
"rides_summary": {
|
||||
"total_count": 4,
|
||||
"sample": [
|
||||
{
|
||||
"id": 591,
|
||||
"name": "Cyclone",
|
||||
"slug": "cyclone",
|
||||
"category": "FR",
|
||||
"status": "OPERATING",
|
||||
"average_rating": "8.91"
|
||||
}
|
||||
// ... up to 10 rides
|
||||
],
|
||||
"full_list_url": "/api/v1/parks/cedar-point/rides/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **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
|
||||
### Paginated Rides Response
|
||||
```json
|
||||
{
|
||||
"count": 4,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 591,
|
||||
"name": "Cyclone",
|
||||
"slug": "cyclone",
|
||||
"category": "FR",
|
||||
"status": "OPERATING",
|
||||
"description": "Exciting FR ride with thrilling elements",
|
||||
"park": {
|
||||
"id": 249,
|
||||
"name": "Cedar Point",
|
||||
"slug": "cedar-point"
|
||||
},
|
||||
"average_rating": "8.91",
|
||||
"capacity_per_hour": 1359,
|
||||
"opening_date": "1999-10-10"
|
||||
}
|
||||
// ... more rides
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Notes
|
||||
## Historical Context
|
||||
|
||||
- Response includes optimized database queries with `select_related` and `prefetch_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
|
||||
The `/detail/` endpoint was temporarily removed during API refactoring but has been restored based on user feedback. It provides a middle-ground solution between the basic park endpoint and separate rides pagination, offering comprehensive park data with a rides preview in a single request.
|
||||
|
||||
Reference in New Issue
Block a user