mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 17:51:08 -05:00
7.4 KiB
7.4 KiB
Data Documentation
Database Schema
Core Models
Parks
CREATE TABLE parks_park (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
slug VARCHAR(255) UNIQUE NOT NULL,
description TEXT,
status VARCHAR(20) DEFAULT 'OPERATING',
opening_date DATE,
closing_date DATE,
operating_season VARCHAR(255),
size_acres DECIMAL(10,2),
website VARCHAR(200),
average_rating DECIMAL(3,2),
ride_count INTEGER,
coaster_count INTEGER,
owner_id INTEGER REFERENCES companies_company(id),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Rides
CREATE TABLE rides_ride (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(20),
park_id INTEGER REFERENCES parks_park(id),
area_id INTEGER REFERENCES parks_parkarea(id),
manufacturer_id INTEGER REFERENCES companies_company(id),
designer_id INTEGER REFERENCES designers_designer(id),
opening_date DATE,
closing_date DATE,
height_requirement INTEGER,
ride_type VARCHAR(50),
thrill_rating INTEGER,
created_at TIMESTAMP,
updated_at TIMESTAMP,
UNIQUE(park_id, slug)
);
Reviews
CREATE TABLE reviews_review (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
rating DECIMAL(3,2),
status VARCHAR(20),
author_id INTEGER REFERENCES auth_user(id),
content_type_id INTEGER REFERENCES django_content_type(id),
object_id INTEGER,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Entity Relationships
erDiagram
Park ||--o{ ParkArea : "contains"
Park ||--o{ Ride : "has"
Park ||--o{ Photo : "has"
Park ||--o{ Review : "receives"
ParkArea ||--o{ Ride : "contains"
Ride ||--o{ Photo : "has"
Ride ||--o{ Review : "receives"
Company ||--o{ Park : "owns"
Company ||--o{ Ride : "manufactures"
Designer ||--o{ Ride : "designs"
User ||--o{ Review : "writes"
Data Models
Content Models
Park Model
- Core information about theme parks
- Location data through GenericRelation
- Media attachments
- Historical tracking
- Owner relationship
Ride Model
- Technical specifications
- Park and area relationships
- Manufacturer and designer links
- Operation status tracking
- Safety requirements
Review Model
- Generic foreign key for flexibility
- Rating system
- Media attachments
- Moderation status
- Author tracking
Supporting Models
Location Model
class Location(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
address = models.CharField(max_length=255)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100)
country = models.CharField(max_length=100)
postal_code = models.CharField(max_length=20)
latitude = models.DecimalField(max_digits=9, decimal_places=6)
longitude = models.DecimalField(max_digits=9, decimal_places=6)
Media Model
class Photo(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
file = models.ImageField(upload_to='photos/')
caption = models.CharField(max_length=255)
taken_at = models.DateTimeField(null=True)
uploaded_at = models.DateTimeField(auto_now_add=True)
Storage Strategies
Database Storage
PostgreSQL Configuration
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'thrillwiki',
'CONN_MAX_AGE': 60,
'OPTIONS': {
'client_encoding': 'UTF8',
},
}
}
Indexing Strategy
-- Performance indexes
CREATE INDEX idx_park_slug ON parks_park(slug);
CREATE INDEX idx_ride_slug ON rides_ride(slug);
CREATE INDEX idx_review_content_type ON reviews_review(content_type_id, object_id);
File Storage
Media Storage
# Media storage configuration
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
# File upload handlers
FILE_UPLOAD_HANDLERS = [
'django.core.files.uploadhandler.MemoryFileUploadHandler',
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
]
Directory Structure
media/
├── photos/
│ ├── parks/
│ ├── rides/
│ └── reviews/
├── avatars/
└── documents/
Caching Strategy
Cache Configuration
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
Cache Keys
# Cache key patterns
CACHE_KEYS = {
'park_detail': 'park:{slug}',
'ride_list': 'park:{park_slug}:rides',
'review_count': 'content:{type}:{id}:reviews',
}
Data Migration
Migration Strategy
- Schema migrations via Django
- Data migrations for model changes
- Content migrations for large updates
Example Migration
# migrations/0002_add_park_status.py
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('parks', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='park',
name='status',
field=models.CharField(
max_length=20,
choices=[
('OPERATING', 'Operating'),
('CLOSED', 'Closed'),
],
default='OPERATING'
),
),
]
Data Protection
Backup Strategy
- Daily database backups
- Media files backup
- Retention policy management
Backup Configuration
# backup settings
BACKUP_ROOT = os.path.join(BASE_DIR, 'backups')
BACKUP_RETENTION_DAYS = 30
BACKUP_COMPRESSION = True
Data Validation
Model Validation
class Park(models.Model):
def clean(self):
if self.closing_date and self.opening_date:
if self.closing_date < self.opening_date:
raise ValidationError({
'closing_date': 'Closing date cannot be before opening date'
})
Form Validation
class RideForm(forms.ModelForm):
def clean_height_requirement(self):
height = self.cleaned_data['height_requirement']
if height and height < 0:
raise forms.ValidationError('Height requirement cannot be negative')
return height
Data Access Patterns
QuerySet Optimization
# Optimized query pattern
Park.objects.select_related('owner')\
.prefetch_related('rides', 'areas')\
.filter(status='OPERATING')
Caching Pattern
def get_park_detail(slug):
cache_key = f'park:{slug}'
park = cache.get(cache_key)
if not park:
park = Park.objects.get(slug=slug)
cache.set(cache_key, park, timeout=3600)
return park
Monitoring and Metrics
Database Metrics
- Query performance
- Cache hit rates
- Storage usage
- Connection pool status
Collection Configuration
LOGGING = {
'handlers': {
'db_log': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/db.log',
},
},
}