Add merge migrations for parks, companies, and moderation apps; update EmailConfiguration, Review, Photo, TopList, and TopListItem models to use pghistory for historical tracking

This commit is contained in:
pacnpal
2025-02-09 16:00:10 -05:00
parent 64d9943d86
commit 2db29fa866
30 changed files with 779 additions and 1654 deletions

View File

@@ -0,0 +1,110 @@
# Generated by Django 5.1.4 on 2025-02-09 18:42
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("accounts", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="TopListEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("title", models.CharField(max_length=100)),
("category", models.CharField(max_length=2)),
("description", models.TextField(blank=True)),
("created_at", models.DateTimeField()),
("updated_at", models.DateTimeField()),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="accounts.toplist")),
("user", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="TopListItemEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("object_id", models.PositiveIntegerField()),
("rank", models.PositiveIntegerField()),
("notes", models.TextField(blank=True)),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="accounts.toplistitem")),
("content_type", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="contenttypes.contenttype")),
("top_list", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="accounts.toplist")),
],
options={
"abstract": False,
},
),
pgtrigger.migrations.AddTrigger(
model_name="toplist",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "accounts_toplistevent" ("category", "created_at", "description", "id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "title", "updated_at", "user_id") VALUES (NEW."category", NEW."created_at", NEW."description", NEW."id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."title", NEW."updated_at", NEW."user_id"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_toplist",
table="accounts_toplist",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="toplist",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "accounts_toplistevent" ("category", "created_at", "description", "id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "title", "updated_at", "user_id") VALUES (NEW."category", NEW."created_at", NEW."description", NEW."id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."title", NEW."updated_at", NEW."user_id"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_toplist",
table="accounts_toplist",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="toplistitem",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "accounts_toplistitemevent" ("content_type_id", "id", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "rank", "top_list_id") VALUES (NEW."content_type_id", NEW."id", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."rank", NEW."top_list_id"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_toplistitem",
table="accounts_toplistitem",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="toplistitem",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "accounts_toplistitemevent" ("content_type_id", "id", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "rank", "top_list_id") VALUES (NEW."content_type_id", NEW."id", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."rank", NEW."top_list_id"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_toplistitem",
table="accounts_toplistitem",
when="AFTER",
),
),
),
]

View File

@@ -7,6 +7,8 @@ from io import BytesIO
import base64
import os
import secrets
from history_tracking.models import TrackedModel
import pghistory
def generate_random_id(model_class, id_field):
"""Generate a random ID starting at 4 digits, expanding to 5 if needed"""
@@ -158,7 +160,8 @@ class PasswordReset(models.Model):
verbose_name = "Password Reset"
verbose_name_plural = "Password Resets"
class TopList(models.Model):
@pghistory.track()
class TopList(TrackedModel):
class Categories(models.TextChoices):
ROLLER_COASTER = 'RC', _('Roller Coaster')
DARK_RIDE = 'DR', _('Dark Ride')
@@ -186,7 +189,8 @@ class TopList(models.Model):
def __str__(self):
return f"{self.user.get_display_name()}'s {self.category} Top List: {self.title}"
class TopListItem(models.Model):
@pghistory.track()
class TopListItem(TrackedModel):
top_list = models.ForeignKey(
TopList,
on_delete=models.CASCADE,

View File

@@ -0,0 +1,68 @@
# Generated by Django 5.1.4 on 2025-02-09 17:51
import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("companies", "0003_companyevent_manufacturerevent"),
]
operations = [
pgtrigger.migrations.AddTrigger(
model_name="company",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "companies_companyevent" ("created_at", "description", "headquarters", "id", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "slug", "total_parks", "total_rides", "updated_at", "website") VALUES (NEW."created_at", NEW."description", NEW."headquarters", NEW."id", NEW."name", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."slug", NEW."total_parks", NEW."total_rides", NEW."updated_at", NEW."website"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_company",
table="companies_company",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="company",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "companies_companyevent" ("created_at", "description", "headquarters", "id", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "slug", "total_parks", "total_rides", "updated_at", "website") VALUES (NEW."created_at", NEW."description", NEW."headquarters", NEW."id", NEW."name", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."slug", NEW."total_parks", NEW."total_rides", NEW."updated_at", NEW."website"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_company",
table="companies_company",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="manufacturer",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "companies_manufacturerevent" ("created_at", "description", "headquarters", "id", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "slug", "total_rides", "total_roller_coasters", "updated_at", "website") VALUES (NEW."created_at", NEW."description", NEW."headquarters", NEW."id", NEW."name", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."slug", NEW."total_rides", NEW."total_roller_coasters", NEW."updated_at", NEW."website"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_manufacturer",
table="companies_manufacturer",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="manufacturer",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "companies_manufacturerevent" ("created_at", "description", "headquarters", "id", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "slug", "total_rides", "total_roller_coasters", "updated_at", "website") VALUES (NEW."created_at", NEW."description", NEW."headquarters", NEW."id", NEW."name", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."slug", NEW."total_rides", NEW."total_roller_coasters", NEW."updated_at", NEW."website"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_manufacturer",
table="companies_manufacturer",
when="AFTER",
),
),
),
]

View File

@@ -11,7 +11,6 @@ class Migration(migrations.Migration):
dependencies = [
("companies", "0003_companyevent_manufacturerevent"),
("pghistory", "0006_delete_aggregateevent"),
("rides", "0010_rideevent_ridemodelevent_and_more"),
]
operations = [

View File

@@ -0,0 +1,13 @@
# Generated by Django 5.1.4 on 2025-02-09 19:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("companies", "0004_add_pghistory_triggers"),
("companies", "0004_delete_designer_alter_company_id_and_more"),
]
operations = []

View File

@@ -1,14 +1,27 @@
import pghistory
from django.contrib.auth.models import AnonymousUser
from django.core.handlers.wsgi import WSGIRequest
def setup_pghistory_context():
class RequestContextProvider(pghistory.context):
"""Custom context provider for pghistory that extracts information from the request."""
def __call__(self, request: WSGIRequest) -> dict:
return {
'user': str(request.user) if request.user and not isinstance(request.user, AnonymousUser) else None,
'ip': request.META.get('REMOTE_ADDR'),
'user_agent': request.META.get('HTTP_USER_AGENT'),
'session_key': request.session.session_key if hasattr(request, 'session') else None
}
# Initialize the context provider
request_context = RequestContextProvider()
class PgHistoryContextMiddleware:
"""
Set up pghistory context middleware to track request information.
This function configures what contextual information is stored
with each history record.
Middleware that ensures request object is available to pghistory context.
"""
pghistory.context(lambda request: {
'user': str(request.user) if request.user.is_authenticated else None,
'ip': request.META.get('REMOTE_ADDR'),
'user_agent': request.META.get('HTTP_USER_AGENT'),
'session_key': request.session.session_key
})
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response

View File

@@ -0,0 +1,63 @@
# Generated by Django 5.1.4 on 2025-02-09 18:31
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("email_service", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
]
operations = [
migrations.CreateModel(
name="EmailConfigurationEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("api_key", models.CharField(max_length=255)),
("from_email", models.EmailField(max_length=254)),
("from_name", models.CharField(max_length=255)),
("reply_to", models.EmailField(max_length=254)),
("created_at", models.DateTimeField()),
("updated_at", models.DateTimeField()),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="email_service.emailconfiguration")),
("site", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="django.contrib.sites.models.Site")),
],
options={
"abstract": False,
},
),
pgtrigger.migrations.AddTrigger(
model_name="emailconfiguration",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "email_service_emailconfigurationevent" ("api_key", "created_at", "from_email", "from_name", "id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "reply_to", "site_id", "updated_at") VALUES (NEW."api_key", NEW."created_at", NEW."from_email", NEW."from_name", NEW."id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."reply_to", NEW."site_id", NEW."updated_at"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_emailconfig",
table="email_service_emailconfiguration",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="emailconfiguration",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "email_service_emailconfigurationevent" ("api_key", "created_at", "from_email", "from_name", "id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "reply_to", "site_id", "updated_at") VALUES (NEW."api_key", NEW."created_at", NEW."from_email", NEW."from_name", NEW."id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."reply_to", NEW."site_id", NEW."updated_at"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_emailconfig",
table="email_service_emailconfiguration",
when="AFTER",
),
),
),
]

View File

@@ -1,7 +1,10 @@
from django.db import models
from django.contrib.sites.models import Site
from history_tracking.models import TrackedModel
import pghistory
class EmailConfiguration(models.Model):
@pghistory.track()
class EmailConfiguration(TrackedModel):
api_key = models.CharField(max_length=255)
from_email = models.EmailField()
from_name = models.CharField(max_length=255, help_text="The name that will appear in the From field of emails")

View File

@@ -0,0 +1,69 @@
# Generated by Django 5.1.4 on 2025-02-09 18:01
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("media", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="PhotoEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("image", models.ImageField(max_length=255, upload_to="events")),
("caption", models.CharField(blank=True, max_length=255)),
("alt_text", models.CharField(blank=True, max_length=255)),
("is_primary", models.BooleanField(default=False)),
("is_approved", models.BooleanField(default=False)),
("created_at", models.DateTimeField()),
("updated_at", models.DateTimeField()),
("date_taken", models.DateTimeField(blank=True, null=True)),
("object_id", models.PositiveIntegerField()),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="media.photo")),
("content_type", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="contenttypes.contenttype")),
("uploaded_by", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
],
options={
"abstract": False,
},
),
pgtrigger.migrations.AddTrigger(
model_name="photo",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "media_photoevent" ("alt_text", "caption", "content_type_id", "created_at", "date_taken", "id", "image", "is_approved", "is_primary", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at", "uploaded_by_id") VALUES (NEW."alt_text", NEW."caption", NEW."content_type_id", NEW."created_at", NEW."date_taken", NEW."id", NEW."image", NEW."is_approved", NEW."is_primary", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."updated_at", NEW."uploaded_by_id"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_photo",
table="media_photo",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="photo",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "media_photoevent" ("alt_text", "caption", "content_type_id", "created_at", "date_taken", "id", "image", "is_approved", "is_primary", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at", "uploaded_by_id") VALUES (NEW."alt_text", NEW."caption", NEW."content_type_id", NEW."created_at", NEW."date_taken", NEW."id", NEW."image", NEW."is_approved", NEW."is_primary", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."updated_at", NEW."uploaded_by_id"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_photo",
table="media_photo",
when="AFTER",
),
),
),
]

View File

@@ -11,6 +11,8 @@ from datetime import datetime
from .storage import MediaStorage
from rides.models import Ride
from django.utils import timezone
from history_tracking.models import TrackedModel
import pghistory
def photo_upload_path(instance: models.Model, filename: str) -> str:
"""Generate upload path for photos using normalized filenames"""
@@ -38,7 +40,8 @@ def photo_upload_path(instance: models.Model, filename: str) -> str:
# For park photos, store directly in park directory
return f"park/{identifier}/{base_filename}"
class Photo(models.Model):
@pghistory.track()
class Photo(TrackedModel):
"""Generic photo model that can be attached to any model"""
image = models.ImageField(
upload_to=photo_upload_path, # type: ignore[arg-type]

View File

@@ -1,98 +1,41 @@
# PGHistory Migration Progress
# Foreign Key Constraint Resolution - 2025-02-09 (Updated)
## All Migrations Complete! 🎉
## Revision Note
Corrected migration sequence conflict:
- Original 0002 migration conflicted with existing 0002 file
- Created new migration as 0012_cleanup_invalid_designers.py
- Deleted conflicting 0002_cleanup_invalid_designers.py
### Latest Migration
- `location/migrations/0002_locationevent_remove_historicallocation_content_type_and_more.py`
- Created LocationEvent model
- Removed simple-history fields
- Set up pghistory triggers
- Cleaned up historical models
## Updated Resolution Steps
1. Created conflict-free migration 0012
2. Verified migration dependencies:
```python
dependencies = [
('rides', '0011_merge_20250209_1143'),
('designers', '0001_initial'),
]
```
3. New migration command:
```bash
python manage.py migrate rides 0012_cleanup_invalid_designers
```
### Previously Completed Migrations
1. Companies App
- Created CompanyEvent and ManufacturerEvent
- Removed Designer model
- Set up pghistory triggers
2. Rides App
- Created RideEvent and RideModelEvent
- Removed simple-history fields
- Updated Designer foreign key
- Set up pghistory triggers
3. Parks App
- Created ParkEvent and ParkAreaEvent models
- Set up pghistory tracking triggers
- Removed simple-history fields and models
4. Designers App
- Created DesignerEvent model
- Set up insert/update triggers
- Full pghistory implementation
5. Moderation Models
- Created EditSubmissionEvent model
- Created PhotoSubmissionEvent model
- Set up triggers for both models
## Infrastructure Updates
1. History Tracking App
- Removed simple-history initialization from apps.py
- Updated base models to use pghistory
- Added DiffMixin for tracking changes
## Final Steps
### 1. Remove django-simple-history
```bash
# Update requirements.txt
- Remove django-simple-history==3.8.0
```
### 2. Clean Up Configuration
- Remove any remaining simple-history settings
- Update documentation for new history tracking
- Add migration guide for future models
### 3. Testing
1. Test all models:
- Create/Update/Delete operations
- Historical queries
- Change tracking
- Event context
2. Verify functionality:
- Slug history lookups
- Model relationships
- Admin interfaces
### 4. Documentation Updates
1. Update model documentation
2. Add pghistory usage examples
3. Document migration patterns
4. Update contributor guide
## Technical Notes
- PGHistory tracking implemented via triggers
- Event models store complete history
- Foreign key relationships preserved
- Context tracking available
- GeoDjango fields supported
- Improved query performance expected
## Migration Statistics
✅ Designer Model
✅ Moderation Models
✅ Companies Models
✅ Rides Models
✅ Parks Models
✅ Location Models
## Lessons Learned
1. Keep backward compatibility during transition
2. Migrate models in dependency order
3. Test thoroughly after each migration
4. Update related code incrementally
5. Maintain documentation throughout
## PGHistory Migration Fix - 2025-02-09
Foreign key constraint violation during pghistory migration:
1. Issue: `rides_ride_designer_id_172b997d_fk_designers_designer_id` constraint violation during 0010_rideevent migration
2. Resolution:
- Created new cleanup migration (0009_cleanup_invalid_designers_pre_events.py) to run before event table creation
- Updated migration dependencies to ensure proper sequencing:
```python
# 0009_cleanup_invalid_designers_pre_events.py
dependencies = [
('rides', '0008_historicalride_post_closing_status_and_more'),
('designers', '0001_initial'),
]
```
- Created merge migration (0013_merge_20250209_1214.py) to resolve multiple leaf nodes
3. Final Migration Sequence:
- Base migrations up to 0008
- Cleanup migration (0009_cleanup_invalid_designers_pre_events)
- Event table creation (0010_rideevent_ridemodelevent_and_more)
- Merge migrations (0011, 0012, 0013)

View File

@@ -0,0 +1,123 @@
# Generated by Django 5.1.4 on 2025-02-09 18:26
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("moderation", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="EditSubmissionEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("object_id", models.PositiveIntegerField(blank=True, null=True)),
("submission_type", models.CharField(max_length=10)),
("changes", models.JSONField()),
("moderator_changes", models.JSONField(blank=True, null=True)),
("reason", models.TextField()),
("source", models.TextField(blank=True)),
("status", models.CharField(max_length=20)),
("created_at", models.DateTimeField()),
("handled_at", models.DateTimeField(blank=True, null=True)),
("notes", models.TextField(blank=True)),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="moderation.editsubmission")),
("content_type", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="contenttypes.contenttype")),
("handled_by", models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
("user", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="PhotoSubmissionEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("object_id", models.PositiveIntegerField()),
("photo", models.ImageField(upload_to="events/photos/")),
("caption", models.CharField(blank=True, max_length=255)),
("date_taken", models.DateField(blank=True, null=True)),
("status", models.CharField(max_length=20)),
("created_at", models.DateTimeField()),
("handled_at", models.DateTimeField(blank=True, null=True)),
("notes", models.TextField(blank=True)),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="moderation.photosubmission")),
("content_type", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="contenttypes.contenttype")),
("handled_by", models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
("user", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
],
options={
"abstract": False,
},
),
pgtrigger.migrations.AddTrigger(
model_name="editsubmission",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "moderation_editsubmissionevent" ("changes", "content_type_id", "created_at", "handled_at", "handled_by_id", "id", "moderator_changes", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "reason", "source", "status", "submission_type", "user_id") VALUES (NEW."changes", NEW."content_type_id", NEW."created_at", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."moderator_changes", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."reason", NEW."source", NEW."status", NEW."submission_type", NEW."user_id"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_editsubmission",
table="moderation_editsubmission",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="editsubmission",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "moderation_editsubmissionevent" ("changes", "content_type_id", "created_at", "handled_at", "handled_by_id", "id", "moderator_changes", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "reason", "source", "status", "submission_type", "user_id") VALUES (NEW."changes", NEW."content_type_id", NEW."created_at", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."moderator_changes", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."reason", NEW."source", NEW."status", NEW."submission_type", NEW."user_id"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_editsubmission",
table="moderation_editsubmission",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="photosubmission",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "moderation_photosubmissionevent" ("caption", "content_type_id", "created_at", "date_taken", "handled_at", "handled_by_id", "id", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "photo", "status", "user_id") VALUES (NEW."caption", NEW."content_type_id", NEW."created_at", NEW."date_taken", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."photo", NEW."status", NEW."user_id"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_photosubmission",
table="moderation_photosubmission",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="photosubmission",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "moderation_photosubmissionevent" ("caption", "content_type_id", "created_at", "date_taken", "handled_at", "handled_by_id", "id", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "photo", "status", "user_id") VALUES (NEW."caption", NEW."content_type_id", NEW."created_at", NEW."date_taken", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."photo", NEW."status", NEW."user_id"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_photosubmission",
table="moderation_photosubmission",
when="AFTER",
),
),
),
]

View File

@@ -0,0 +1,13 @@
# Generated by Django 5.1.4 on 2025-02-09 19:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("moderation", "0002_add_pghistory"),
("moderation", "0005_editsubmissionevent_photosubmissionevent_and_more"),
]
operations = []

View File

@@ -0,0 +1,154 @@
# Generated by Django 5.1.4 on 2025-02-09 17:54
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("parks", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
]
operations = [
migrations.CreateModel(
name="ParkEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(db_index=False, max_length=255)),
("description", models.TextField(blank=True)),
("status", models.CharField(
choices=[
("OPERATING", "Operating"),
("CLOSED_TEMP", "Temporarily Closed"),
("CLOSED_PERM", "Permanently Closed"),
("UNDER_CONSTRUCTION", "Under Construction"),
("DEMOLISHED", "Demolished"),
("RELOCATED", "Relocated"),
],
default="OPERATING",
max_length=20,
)),
("opening_date", models.DateField(blank=True, null=True)),
("closing_date", models.DateField(blank=True, null=True)),
("operating_season", models.CharField(blank=True, max_length=255)),
("size_acres", models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)),
("website", models.URLField(blank=True)),
("average_rating", models.DecimalField(blank=True, decimal_places=2, max_digits=3, null=True)),
("ride_count", models.IntegerField(blank=True, null=True)),
("coaster_count", models.IntegerField(blank=True, null=True)),
("created_at", models.DateTimeField(auto_now_add=True, null=True)),
("updated_at", models.DateTimeField(auto_now=True)),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="parks.park")),
("owner", models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="companies.company")),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="ParkAreaEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(db_index=False, max_length=255)),
("description", models.TextField(blank=True)),
("opening_date", models.DateField(blank=True, null=True)),
("closing_date", models.DateField(blank=True, null=True)),
("created_at", models.DateTimeField(auto_now_add=True, null=True)),
("updated_at", models.DateTimeField(auto_now=True)),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="parks.parkarea")),
("park", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="parks.park")),
],
options={
"abstract": False,
},
),
pgtrigger.migrations.AddTrigger(
model_name="park",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "parks_parkevent" ("average_rating", "closing_date", "coaster_count", "created_at", "description", "id", "name", "operating_season", "opening_date", "owner_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "ride_count", "size_acres", "slug", "status", "updated_at", "website") VALUES (NEW."average_rating", NEW."closing_date", NEW."coaster_count", NEW."created_at", NEW."description", NEW."id", NEW."name", NEW."operating_season", NEW."opening_date", NEW."owner_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."ride_count", NEW."size_acres", NEW."slug", NEW."status", NEW."updated_at", NEW."website"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_park",
table="parks_park",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="park",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "parks_parkevent" ("average_rating", "closing_date", "coaster_count", "created_at", "description", "id", "name", "operating_season", "opening_date", "owner_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "ride_count", "size_acres", "slug", "status", "updated_at", "website") VALUES (NEW."average_rating", NEW."closing_date", NEW."coaster_count", NEW."created_at", NEW."description", NEW."id", NEW."name", NEW."operating_season", NEW."opening_date", NEW."owner_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."ride_count", NEW."size_acres", NEW."slug", NEW."status", NEW."updated_at", NEW."website"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_park",
table="parks_park",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="parkarea",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "parks_parkareaevent" ("closing_date", "created_at", "description", "id", "name", "opening_date", "park_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "slug", "updated_at") VALUES (NEW."closing_date", NEW."created_at", NEW."description", NEW."id", NEW."name", NEW."opening_date", NEW."park_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."slug", NEW."updated_at"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_parkarea",
table="parks_parkarea",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="parkarea",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "parks_parkareaevent" ("closing_date", "created_at", "description", "id", "name", "opening_date", "park_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "slug", "updated_at") VALUES (NEW."closing_date", NEW."created_at", NEW."description", NEW."id", NEW."name", NEW."opening_date", NEW."park_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."slug", NEW."updated_at"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_parkarea",
table="parks_parkarea",
when="AFTER",
),
),
),
migrations.RemoveField(
model_name="historicalpark",
name="history_user",
),
migrations.RemoveField(
model_name="historicalpark",
name="owner",
),
migrations.RemoveField(
model_name="historicalparkarea",
name="history_user",
),
migrations.RemoveField(
model_name="historicalparkarea",
name="park",
),
migrations.DeleteModel(
name="HistoricalPark",
),
migrations.DeleteModel(
name="HistoricalParkArea",
),
]

View File

@@ -0,0 +1,13 @@
# Generated by Django 5.1.4 on 2025-02-09 19:48
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("parks", "0002_parkareaevent_parkevent_and_more"),
("parks", "0002_switch_to_pghistory"),
]
operations = []

View File

@@ -9,11 +9,10 @@ django-oauth-toolkit==3.0.1
dj-rest-auth==7.0.1 # Added for REST authentication endpoints
pyjwt==2.10.1
# Database
psycopg2-binary==2.9.10
dj-database-url==2.3.0
django-pghistory==2.9.0 # Added for model history tracking
django-pghistory==2.9.0 # For model history tracking
# Email
requests==2.32.3 # For ForwardEmail.net API
@@ -43,5 +42,4 @@ channels-redis==4.2.1
daphne==4.1.2
# React and Material UI will be handled via npm in the frontend directory
django-simple-history==3.8.0
django-tailwind-cli==2.21.1

View File

@@ -0,0 +1,71 @@
# Generated by Django 5.1.4 on 2025-02-09 18:06
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("reviews", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="ReviewEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("rating", models.PositiveSmallIntegerField()),
("title", models.CharField(max_length=200)),
("content", models.TextField()),
("visit_date", models.DateField()),
("created_at", models.DateTimeField()),
("updated_at", models.DateTimeField()),
("is_published", models.BooleanField()),
("moderation_notes", models.TextField(blank=True)),
("moderated_at", models.DateTimeField(blank=True, null=True)),
("object_id", models.PositiveIntegerField()),
("pgh_context", models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="pghistory.context")),
("pgh_obj", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="events", to="reviews.review")),
("content_type", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to="contenttypes.contenttype")),
("user", models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
("moderated_by", models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name="+", to=settings.AUTH_USER_MODEL)),
],
options={
"abstract": False,
},
),
pgtrigger.migrations.AddTrigger(
model_name="review",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "reviews_reviewevent" ("content", "content_type_id", "created_at", "id", "is_published", "moderated_at", "moderated_by_id", "moderation_notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "rating", "title", "updated_at", "user_id", "visit_date") VALUES (NEW."content", NEW."content_type_id", NEW."created_at", NEW."id", NEW."is_published", NEW."moderated_at", NEW."moderated_by_id", NEW."moderation_notes", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."rating", NEW."title", NEW."updated_at", NEW."user_id", NEW."visit_date"); RETURN NULL;',
operation="INSERT",
pgid="pgtrigger_insert_insert_review",
table="reviews_review",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="review",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "reviews_reviewevent" ("content", "content_type_id", "created_at", "id", "is_published", "moderated_at", "moderated_by_id", "moderation_notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "rating", "title", "updated_at", "user_id", "visit_date") VALUES (NEW."content", NEW."content_type_id", NEW."created_at", NEW."id", NEW."is_published", NEW."moderated_at", NEW."moderated_by_id", NEW."moderation_notes", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."rating", NEW."title", NEW."updated_at", NEW."user_id", NEW."visit_date"); RETURN NULL;',
operation="UPDATE",
pgid="pgtrigger_update_update_review",
table="reviews_review",
when="AFTER",
),
),
),
]

View File

@@ -2,8 +2,11 @@ from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.core.validators import MinValueValidator, MaxValueValidator
from history_tracking.models import TrackedModel
import pghistory
class Review(models.Model):
@pghistory.track()
class Review(TrackedModel):
# Generic relation to allow reviews on different types (rides, parks)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()

View File

@@ -1,507 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-12 18:07
import django.db.models.deletion
import simple_history.models
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("companies", "0001_initial"),
("designers", "0001_initial"),
("parks", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="HistoricalRide",
fields=[
("id", models.BigIntegerField(blank=True, db_index=True)),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(max_length=255)),
("description", models.TextField(blank=True)),
(
"category",
models.CharField(
choices=[
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="OT",
max_length=2,
),
),
("model_name", models.CharField(blank=True, max_length=255)),
(
"status",
models.CharField(
choices=[
("OPERATING", "Operating"),
("CLOSED_TEMP", "Temporarily Closed"),
("CLOSED_PERM", "Permanently Closed"),
("UNDER_CONSTRUCTION", "Under Construction"),
("DEMOLISHED", "Demolished"),
("RELOCATED", "Relocated"),
],
default="OPERATING",
max_length=20,
),
),
("opening_date", models.DateField(blank=True, null=True)),
("closing_date", models.DateField(blank=True, null=True)),
("status_since", models.DateField(blank=True, null=True)),
("min_height_in", models.PositiveIntegerField(blank=True, null=True)),
("max_height_in", models.PositiveIntegerField(blank=True, null=True)),
("accessibility_options", models.TextField(blank=True)),
(
"capacity_per_hour",
models.PositiveIntegerField(blank=True, null=True),
),
(
"ride_duration_seconds",
models.PositiveIntegerField(blank=True, null=True),
),
(
"average_rating",
models.DecimalField(
blank=True, decimal_places=2, max_digits=3, null=True
),
),
("created_at", models.DateTimeField(blank=True, editable=False)),
("updated_at", models.DateTimeField(blank=True, editable=False)),
("history_id", models.AutoField(primary_key=True, serialize=False)),
("history_date", models.DateTimeField(db_index=True)),
("history_change_reason", models.CharField(max_length=100, null=True)),
(
"history_type",
models.CharField(
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
max_length=1,
),
),
(
"designer",
models.ForeignKey(
blank=True,
db_constraint=False,
help_text="The designer/engineering firm responsible for the ride",
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="designers.designer",
),
),
(
"history_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
(
"manufacturer",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="companies.manufacturer",
),
),
(
"park",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="parks.park",
),
),
(
"park_area",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="parks.parkarea",
),
),
],
options={
"verbose_name": "historical ride",
"verbose_name_plural": "historical rides",
"ordering": ("-history_date", "-history_id"),
"get_latest_by": ("history_date", "history_id"),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name="Ride",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(max_length=255)),
("description", models.TextField(blank=True)),
(
"category",
models.CharField(
choices=[
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="OT",
max_length=2,
),
),
("model_name", models.CharField(blank=True, max_length=255)),
(
"status",
models.CharField(
choices=[
("OPERATING", "Operating"),
("CLOSED_TEMP", "Temporarily Closed"),
("CLOSED_PERM", "Permanently Closed"),
("UNDER_CONSTRUCTION", "Under Construction"),
("DEMOLISHED", "Demolished"),
("RELOCATED", "Relocated"),
],
default="OPERATING",
max_length=20,
),
),
("opening_date", models.DateField(blank=True, null=True)),
("closing_date", models.DateField(blank=True, null=True)),
("status_since", models.DateField(blank=True, null=True)),
("min_height_in", models.PositiveIntegerField(blank=True, null=True)),
("max_height_in", models.PositiveIntegerField(blank=True, null=True)),
("accessibility_options", models.TextField(blank=True)),
(
"capacity_per_hour",
models.PositiveIntegerField(blank=True, null=True),
),
(
"ride_duration_seconds",
models.PositiveIntegerField(blank=True, null=True),
),
(
"average_rating",
models.DecimalField(
blank=True, decimal_places=2, max_digits=3, null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"designer",
models.ForeignKey(
blank=True,
help_text="The designer/engineering firm responsible for the ride",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rides",
to="designers.designer",
),
),
(
"manufacturer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="companies.manufacturer",
),
),
(
"park",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="rides",
to="parks.park",
),
),
(
"park_area",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rides",
to="parks.parkarea",
),
),
],
options={
"ordering": ["name"],
"unique_together": {("park", "slug")},
},
),
migrations.CreateModel(
name="HistoricalRollerCoasterStats",
fields=[
("id", models.BigIntegerField(blank=True, db_index=True)),
(
"height_ft",
models.DecimalField(
blank=True, decimal_places=2, max_digits=6, null=True
),
),
(
"length_ft",
models.DecimalField(
blank=True, decimal_places=2, max_digits=7, null=True
),
),
(
"speed_mph",
models.DecimalField(
blank=True, decimal_places=2, max_digits=5, null=True
),
),
("inversions", models.PositiveIntegerField(default=0)),
(
"ride_time_seconds",
models.PositiveIntegerField(blank=True, null=True),
),
("track_type", models.CharField(blank=True, max_length=255)),
(
"track_material",
models.CharField(
blank=True,
choices=[
("STEEL", "Steel"),
("WOOD", "Wood"),
("HYBRID", "Hybrid"),
("OTHER", "Other"),
],
default="STEEL",
max_length=20,
),
),
(
"roller_coaster_type",
models.CharField(
blank=True,
choices=[
("SITDOWN", "Sit-Down"),
("INVERTED", "Inverted"),
("FLYING", "Flying"),
("STANDUP", "Stand-Up"),
("WING", "Wing"),
("SUSPENDED", "Suspended"),
("BOBSLED", "Bobsled"),
("PIPELINE", "Pipeline"),
("MOTORBIKE", "Motorbike"),
("FLOORLESS", "Floorless"),
("DIVE", "Dive"),
("FAMILY", "Family"),
("WILD_MOUSE", "Wild Mouse"),
("SPINNING", "Spinning"),
("FOURTH_DIMENSION", "4th Dimension"),
("OTHER", "Other"),
],
default="SITDOWN",
help_text="The type/style of roller coaster (e.g. Sit-Down, Inverted, Flying)",
max_length=20,
),
),
(
"max_drop_height_ft",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Maximum vertical drop height in feet",
max_digits=6,
null=True,
),
),
(
"launch_type",
models.CharField(
choices=[
("CHAIN", "Chain Lift"),
("CABLE", "Cable Launch"),
("HYDRAULIC", "Hydraulic Launch"),
("LSM", "Linear Synchronous Motor"),
("LIM", "Linear Induction Motor"),
("GRAVITY", "Gravity"),
("OTHER", "Other"),
],
default="CHAIN",
max_length=20,
),
),
("train_style", models.CharField(blank=True, max_length=255)),
("trains_count", models.PositiveIntegerField(blank=True, null=True)),
("cars_per_train", models.PositiveIntegerField(blank=True, null=True)),
("seats_per_car", models.PositiveIntegerField(blank=True, null=True)),
("history_id", models.AutoField(primary_key=True, serialize=False)),
("history_date", models.DateTimeField(db_index=True)),
("history_change_reason", models.CharField(max_length=100, null=True)),
(
"history_type",
models.CharField(
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
max_length=1,
),
),
(
"history_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
(
"ride",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="rides.ride",
),
),
],
options={
"verbose_name": "historical Roller Coaster Statistics",
"verbose_name_plural": "historical Roller Coaster Statistics",
"ordering": ("-history_date", "-history_id"),
"get_latest_by": ("history_date", "history_id"),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name="RollerCoasterStats",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
(
"height_ft",
models.DecimalField(
blank=True, decimal_places=2, max_digits=6, null=True
),
),
(
"length_ft",
models.DecimalField(
blank=True, decimal_places=2, max_digits=7, null=True
),
),
(
"speed_mph",
models.DecimalField(
blank=True, decimal_places=2, max_digits=5, null=True
),
),
("inversions", models.PositiveIntegerField(default=0)),
(
"ride_time_seconds",
models.PositiveIntegerField(blank=True, null=True),
),
("track_type", models.CharField(blank=True, max_length=255)),
(
"track_material",
models.CharField(
blank=True,
choices=[
("STEEL", "Steel"),
("WOOD", "Wood"),
("HYBRID", "Hybrid"),
("OTHER", "Other"),
],
default="STEEL",
max_length=20,
),
),
(
"roller_coaster_type",
models.CharField(
blank=True,
choices=[
("SITDOWN", "Sit-Down"),
("INVERTED", "Inverted"),
("FLYING", "Flying"),
("STANDUP", "Stand-Up"),
("WING", "Wing"),
("SUSPENDED", "Suspended"),
("BOBSLED", "Bobsled"),
("PIPELINE", "Pipeline"),
("MOTORBIKE", "Motorbike"),
("FLOORLESS", "Floorless"),
("DIVE", "Dive"),
("FAMILY", "Family"),
("WILD_MOUSE", "Wild Mouse"),
("SPINNING", "Spinning"),
("FOURTH_DIMENSION", "4th Dimension"),
("OTHER", "Other"),
],
default="SITDOWN",
help_text="The type/style of roller coaster (e.g. Sit-Down, Inverted, Flying)",
max_length=20,
),
),
(
"max_drop_height_ft",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Maximum vertical drop height in feet",
max_digits=6,
null=True,
),
),
(
"launch_type",
models.CharField(
choices=[
("CHAIN", "Chain Lift"),
("CABLE", "Cable Launch"),
("HYDRAULIC", "Hydraulic Launch"),
("LSM", "Linear Synchronous Motor"),
("LIM", "Linear Induction Motor"),
("GRAVITY", "Gravity"),
("OTHER", "Other"),
],
default="CHAIN",
max_length=20,
),
),
("train_style", models.CharField(blank=True, max_length=255)),
("trains_count", models.PositiveIntegerField(blank=True, null=True)),
("cars_per_train", models.PositiveIntegerField(blank=True, null=True)),
("seats_per_car", models.PositiveIntegerField(blank=True, null=True)),
(
"ride",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="coaster_stats",
to="rides.ride",
),
),
],
options={
"verbose_name": "Roller Coaster Statistics",
"verbose_name_plural": "Roller Coaster Statistics",
},
),
]

View File

@@ -1,40 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-12 20:23
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("companies", "0002_add_designer_model"),
("rides", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="historicalride",
name="designer",
field=models.ForeignKey(
blank=True,
db_constraint=False,
help_text="The designer/engineering firm responsible for the ride",
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="companies.designer",
),
),
migrations.AlterField(
model_name="ride",
name="designer",
field=models.ForeignKey(
blank=True,
help_text="The designer/engineering firm responsible for the ride",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rides",
to="companies.designer",
),
),
]

View File

@@ -1,160 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-12 21:40
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("companies", "0002_add_designer_model"),
("rides", "0002_alter_historicalride_designer_alter_ride_designer"),
]
operations = [
migrations.RemoveField(
model_name="historicalride",
name="accessibility_options",
),
migrations.RemoveField(
model_name="ride",
name="accessibility_options",
),
migrations.AlterField(
model_name="historicalride",
name="category",
field=models.CharField(
blank=True,
choices=[
("", "Select ride type... *"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
migrations.AlterField(
model_name="historicalride",
name="designer",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="companies.designer",
),
),
migrations.AlterField(
model_name="historicalrollercoasterstats",
name="max_drop_height_ft",
field=models.DecimalField(
blank=True, decimal_places=2, max_digits=6, null=True
),
),
migrations.AlterField(
model_name="historicalrollercoasterstats",
name="roller_coaster_type",
field=models.CharField(
blank=True,
choices=[
("SITDOWN", "Sit-Down"),
("INVERTED", "Inverted"),
("FLYING", "Flying"),
("STANDUP", "Stand-Up"),
("WING", "Wing"),
("SUSPENDED", "Suspended"),
("BOBSLED", "Bobsled"),
("PIPELINE", "Pipeline"),
("MOTORBIKE", "Motorbike"),
("FLOORLESS", "Floorless"),
("DIVE", "Dive"),
("FAMILY", "Family"),
("WILD_MOUSE", "Wild Mouse"),
("SPINNING", "Spinning"),
("FOURTH_DIMENSION", "4th Dimension"),
("OTHER", "Other"),
],
default="SITDOWN",
max_length=20,
),
),
migrations.AlterField(
model_name="ride",
name="category",
field=models.CharField(
blank=True,
choices=[
("", "Select ride type... *"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
migrations.AlterField(
model_name="ride",
name="designer",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rides",
to="companies.designer",
),
),
migrations.AlterField(
model_name="ride",
name="manufacturer",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="companies.manufacturer",
),
),
migrations.AlterField(
model_name="rollercoasterstats",
name="max_drop_height_ft",
field=models.DecimalField(
blank=True, decimal_places=2, max_digits=6, null=True
),
),
migrations.AlterField(
model_name="rollercoasterstats",
name="roller_coaster_type",
field=models.CharField(
blank=True,
choices=[
("SITDOWN", "Sit-Down"),
("INVERTED", "Inverted"),
("FLYING", "Flying"),
("STANDUP", "Stand-Up"),
("WING", "Wing"),
("SUSPENDED", "Suspended"),
("BOBSLED", "Bobsled"),
("PIPELINE", "Pipeline"),
("MOTORBIKE", "Motorbike"),
("FLOORLESS", "Floorless"),
("DIVE", "Dive"),
("FAMILY", "Family"),
("WILD_MOUSE", "Wild Mouse"),
("SPINNING", "Spinning"),
("FOURTH_DIMENSION", "4th Dimension"),
("OTHER", "Other"),
],
default="SITDOWN",
max_length=20,
),
),
]

View File

@@ -1,49 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-12 21:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("rides", "0003_remove_historicalride_accessibility_options_and_more"),
]
operations = [
migrations.AlterField(
model_name="historicalride",
name="category",
field=models.CharField(
blank=True,
choices=[
("", "Select ride type"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
migrations.AlterField(
model_name="ride",
name="category",
field=models.CharField(
blank=True,
choices=[
("", "Select ride type"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
]

View File

@@ -1,259 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-12 22:27
import django.db.models.deletion
import simple_history.models
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("companies", "0002_add_designer_model"),
("rides", "0004_alter_historicalride_category_alter_ride_category"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name="rollercoasterstats",
name="id",
field=models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
migrations.AlterField(
model_name="rollercoasterstats",
name="launch_type",
field=models.CharField(
choices=[
("CHAIN", "Chain Lift"),
("LSM", "LSM Launch"),
("HYDRAULIC", "Hydraulic Launch"),
("GRAVITY", "Gravity"),
("OTHER", "Other"),
],
default="CHAIN",
max_length=20,
),
),
migrations.AlterField(
model_name="rollercoasterstats",
name="roller_coaster_type",
field=models.CharField(
blank=True,
choices=[
("SITDOWN", "Sit Down"),
("INVERTED", "Inverted"),
("FLYING", "Flying"),
("STANDUP", "Stand Up"),
("WING", "Wing"),
("DIVE", "Dive"),
("FAMILY", "Family"),
("WILD_MOUSE", "Wild Mouse"),
("SPINNING", "Spinning"),
("FOURTH_DIMENSION", "4th Dimension"),
("OTHER", "Other"),
],
default="SITDOWN",
max_length=20,
),
),
migrations.AlterField(
model_name="rollercoasterstats",
name="track_material",
field=models.CharField(
blank=True,
choices=[("STEEL", "Steel"), ("WOOD", "Wood"), ("HYBRID", "Hybrid")],
default="STEEL",
max_length=20,
),
),
migrations.CreateModel(
name="HistoricalRideModel",
fields=[
("id", models.BigIntegerField(blank=True, db_index=True)),
("name", models.CharField(max_length=255)),
("description", models.TextField(blank=True)),
(
"typical_height_ft",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Typical height of this model in feet",
max_digits=6,
null=True,
),
),
(
"typical_speed_mph",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Typical speed of this model in mph",
max_digits=5,
null=True,
),
),
(
"typical_capacity_per_hour",
models.PositiveIntegerField(
blank=True,
help_text="Typical hourly capacity of this model",
null=True,
),
),
(
"category",
models.CharField(
blank=True,
choices=[
("", "Select ride type"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
("created_at", models.DateTimeField(blank=True, editable=False)),
("updated_at", models.DateTimeField(blank=True, editable=False)),
("history_id", models.AutoField(primary_key=True, serialize=False)),
("history_date", models.DateTimeField(db_index=True)),
("history_change_reason", models.CharField(max_length=100, null=True)),
(
"history_type",
models.CharField(
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
max_length=1,
),
),
(
"history_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
(
"manufacturer",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="companies.manufacturer",
),
),
],
options={
"verbose_name": "historical ride model",
"verbose_name_plural": "historical ride models",
"ordering": ("-history_date", "-history_id"),
"get_latest_by": ("history_date", "history_id"),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name="RideModel",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
("name", models.CharField(max_length=255)),
("description", models.TextField(blank=True)),
(
"typical_height_ft",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Typical height of this model in feet",
max_digits=6,
null=True,
),
),
(
"typical_speed_mph",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Typical speed of this model in mph",
max_digits=5,
null=True,
),
),
(
"typical_capacity_per_hour",
models.PositiveIntegerField(
blank=True,
help_text="Typical hourly capacity of this model",
null=True,
),
),
(
"category",
models.CharField(
blank=True,
choices=[
("", "Select ride type"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"manufacturer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="ride_models",
to="companies.manufacturer",
),
),
],
options={
"ordering": ["manufacturer", "name"],
"unique_together": {("manufacturer", "name")},
},
),
migrations.AddField(
model_name="historicalride",
name="ride_model",
field=models.ForeignKey(
blank=True,
db_constraint=False,
help_text="The specific model/type of this ride",
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="rides.ridemodel",
),
),
migrations.AddField(
model_name="ride",
name="ride_model",
field=models.ForeignKey(
blank=True,
help_text="The specific model/type of this ride",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rides",
to="rides.ridemodel",
),
),
migrations.DeleteModel(
name="HistoricalRollerCoasterStats",
),
]

View File

@@ -1,37 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-13 00:20
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("rides", "0005_alter_rollercoasterstats_id_and_more"),
]
operations = [
migrations.RemoveField(
model_name="historicalridemodel",
name="typical_capacity_per_hour",
),
migrations.RemoveField(
model_name="historicalridemodel",
name="typical_height_ft",
),
migrations.RemoveField(
model_name="historicalridemodel",
name="typical_speed_mph",
),
migrations.RemoveField(
model_name="ridemodel",
name="typical_capacity_per_hour",
),
migrations.RemoveField(
model_name="ridemodel",
name="typical_height_ft",
),
migrations.RemoveField(
model_name="ridemodel",
name="typical_speed_mph",
),
]

View File

@@ -1,26 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-13 02:14
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("companies", "0002_add_designer_model"),
("rides", "0006_remove_historicalridemodel_typical_capacity_per_hour_and_more"),
]
operations = [
migrations.AlterField(
model_name="ridemodel",
name="manufacturer",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="ride_models",
to="companies.manufacturer",
),
),
]

View File

@@ -1,75 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-13 04:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("rides", "0007_alter_ridemodel_manufacturer"),
]
operations = [
migrations.AddField(
model_name="historicalride",
name="post_closing_status",
field=models.CharField(
blank=True,
choices=[
("SBNO", "Standing But Not Operating"),
("CLOSED_PERM", "Permanently Closed"),
],
help_text="Status to change to after closing date",
max_length=20,
null=True,
),
),
migrations.AddField(
model_name="ride",
name="post_closing_status",
field=models.CharField(
blank=True,
choices=[
("SBNO", "Standing But Not Operating"),
("CLOSED_PERM", "Permanently Closed"),
],
help_text="Status to change to after closing date",
max_length=20,
null=True,
),
),
migrations.AlterField(
model_name="historicalride",
name="status",
field=models.CharField(
choices=[
("OPERATING", "Operating"),
("SBNO", "Standing But Not Operating"),
("CLOSING", "Closing"),
("CLOSED_PERM", "Permanently Closed"),
("UNDER_CONSTRUCTION", "Under Construction"),
("DEMOLISHED", "Demolished"),
("RELOCATED", "Relocated"),
],
default="OPERATING",
max_length=20,
),
),
migrations.AlterField(
model_name="ride",
name="status",
field=models.CharField(
choices=[
("OPERATING", "Operating"),
("SBNO", "Standing But Not Operating"),
("CLOSING", "Closing"),
("CLOSED_PERM", "Permanently Closed"),
("UNDER_CONSTRUCTION", "Under Construction"),
("DEMOLISHED", "Demolished"),
("RELOCATED", "Relocated"),
],
default="OPERATING",
max_length=20,
),
),
]

View File

@@ -1,21 +0,0 @@
# Generated by Django 5.1.3 on 2024-11-13 04:44
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("rides", "0008_historicalride_post_closing_status_and_more"),
]
operations = [
migrations.RemoveField(
model_name="historicalride",
name="model_name",
),
migrations.RemoveField(
model_name="ride",
name="model_name",
),
]

View File

@@ -1,364 +0,0 @@
# Generated by Django 5.1.4 on 2025-02-09 15:31
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("companies", "0003_companyevent_manufacturerevent"),
(
"designers",
"0002_designerevent_remove_historicaldesigner_history_user_and_more",
),
("parks", "0001_initial"),
("pghistory", "0006_delete_aggregateevent"),
("rides", "0009_remove_historicalride_model_name_and_more"),
]
operations = [
migrations.CreateModel(
name="RideEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(db_index=False, max_length=255)),
("description", models.TextField(blank=True)),
(
"category",
models.CharField(
blank=True,
choices=[
("", "Select ride type"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
(
"status",
models.CharField(
choices=[
("OPERATING", "Operating"),
("SBNO", "Standing But Not Operating"),
("CLOSING", "Closing"),
("CLOSED_PERM", "Permanently Closed"),
("UNDER_CONSTRUCTION", "Under Construction"),
("DEMOLISHED", "Demolished"),
("RELOCATED", "Relocated"),
],
default="OPERATING",
max_length=20,
),
),
(
"post_closing_status",
models.CharField(
blank=True,
choices=[
("SBNO", "Standing But Not Operating"),
("CLOSED_PERM", "Permanently Closed"),
],
help_text="Status to change to after closing date",
max_length=20,
null=True,
),
),
("opening_date", models.DateField(blank=True, null=True)),
("closing_date", models.DateField(blank=True, null=True)),
("status_since", models.DateField(blank=True, null=True)),
("min_height_in", models.PositiveIntegerField(blank=True, null=True)),
("max_height_in", models.PositiveIntegerField(blank=True, null=True)),
(
"capacity_per_hour",
models.PositiveIntegerField(blank=True, null=True),
),
(
"ride_duration_seconds",
models.PositiveIntegerField(blank=True, null=True),
),
(
"average_rating",
models.DecimalField(
blank=True, decimal_places=2, max_digits=3, null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="RideModelEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("name", models.CharField(max_length=255)),
("description", models.TextField(blank=True)),
(
"category",
models.CharField(
blank=True,
choices=[
("", "Select ride type"),
("RC", "Roller Coaster"),
("DR", "Dark Ride"),
("FR", "Flat Ride"),
("WR", "Water Ride"),
("TR", "Transport"),
("OT", "Other"),
],
default="",
max_length=2,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"abstract": False,
},
),
migrations.RemoveField(
model_name="historicalride",
name="designer",
),
migrations.RemoveField(
model_name="historicalride",
name="history_user",
),
migrations.RemoveField(
model_name="historicalride",
name="manufacturer",
),
migrations.RemoveField(
model_name="historicalride",
name="park",
),
migrations.RemoveField(
model_name="historicalride",
name="park_area",
),
migrations.RemoveField(
model_name="historicalride",
name="ride_model",
),
migrations.RemoveField(
model_name="historicalridemodel",
name="history_user",
),
migrations.RemoveField(
model_name="historicalridemodel",
name="manufacturer",
),
migrations.AlterField(
model_name="ride",
name="designer",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="rides",
to="designers.designer",
),
),
pgtrigger.migrations.AddTrigger(
model_name="ride",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "rides_rideevent" ("average_rating", "capacity_per_hour", "category", "closing_date", "created_at", "description", "designer_id", "id", "manufacturer_id", "max_height_in", "min_height_in", "name", "opening_date", "park_area_id", "park_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "post_closing_status", "ride_duration_seconds", "ride_model_id", "slug", "status", "status_since", "updated_at") VALUES (NEW."average_rating", NEW."capacity_per_hour", NEW."category", NEW."closing_date", NEW."created_at", NEW."description", NEW."designer_id", NEW."id", NEW."manufacturer_id", NEW."max_height_in", NEW."min_height_in", NEW."name", NEW."opening_date", NEW."park_area_id", NEW."park_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."post_closing_status", NEW."ride_duration_seconds", NEW."ride_model_id", NEW."slug", NEW."status", NEW."status_since", NEW."updated_at"); RETURN NULL;',
hash="870aa867ae6892f187dc0382e4a6833b5d1267c5",
operation="INSERT",
pgid="pgtrigger_insert_insert_52074",
table="rides_ride",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="ride",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "rides_rideevent" ("average_rating", "capacity_per_hour", "category", "closing_date", "created_at", "description", "designer_id", "id", "manufacturer_id", "max_height_in", "min_height_in", "name", "opening_date", "park_area_id", "park_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "post_closing_status", "ride_duration_seconds", "ride_model_id", "slug", "status", "status_since", "updated_at") VALUES (NEW."average_rating", NEW."capacity_per_hour", NEW."category", NEW."closing_date", NEW."created_at", NEW."description", NEW."designer_id", NEW."id", NEW."manufacturer_id", NEW."max_height_in", NEW."min_height_in", NEW."name", NEW."opening_date", NEW."park_area_id", NEW."park_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."post_closing_status", NEW."ride_duration_seconds", NEW."ride_model_id", NEW."slug", NEW."status", NEW."status_since", NEW."updated_at"); RETURN NULL;',
hash="8bafb42256ee98b4517ae4d39d0e774111794fea",
operation="UPDATE",
pgid="pgtrigger_update_update_4917a",
table="rides_ride",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="ridemodel",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "rides_ridemodelevent" ("category", "created_at", "description", "id", "manufacturer_id", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at") VALUES (NEW."category", NEW."created_at", NEW."description", NEW."id", NEW."manufacturer_id", NEW."name", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."updated_at"); RETURN NULL;',
hash="e9e3c3ec4cb2400b363035534c580c94a3bb1d53",
operation="INSERT",
pgid="pgtrigger_insert_insert_0aaee",
table="rides_ridemodel",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="ridemodel",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "rides_ridemodelevent" ("category", "created_at", "description", "id", "manufacturer_id", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at") VALUES (NEW."category", NEW."created_at", NEW."description", NEW."id", NEW."manufacturer_id", NEW."name", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."updated_at"); RETURN NULL;',
hash="4c8073b866beac402ace852e23974fcb01d24267",
operation="UPDATE",
pgid="pgtrigger_update_update_0ca1a",
table="rides_ridemodel",
when="AFTER",
),
),
),
migrations.AddField(
model_name="rideevent",
name="designer",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="designers.designer",
),
),
migrations.AddField(
model_name="rideevent",
name="manufacturer",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="companies.manufacturer",
),
),
migrations.AddField(
model_name="rideevent",
name="park",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="parks.park",
),
),
migrations.AddField(
model_name="rideevent",
name="park_area",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="parks.parkarea",
),
),
migrations.AddField(
model_name="rideevent",
name="pgh_context",
field=models.ForeignKey(
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="pghistory.context",
),
),
migrations.AddField(
model_name="rideevent",
name="pgh_obj",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="events",
to="rides.ride",
),
),
migrations.AddField(
model_name="rideevent",
name="ride_model",
field=models.ForeignKey(
blank=True,
db_constraint=False,
help_text="The specific model/type of this ride",
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="rides.ridemodel",
),
),
migrations.AddField(
model_name="ridemodelevent",
name="manufacturer",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="companies.manufacturer",
),
),
migrations.AddField(
model_name="ridemodelevent",
name="pgh_context",
field=models.ForeignKey(
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="pghistory.context",
),
),
migrations.AddField(
model_name="ridemodelevent",
name="pgh_obj",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="events",
to="rides.ridemodel",
),
),
migrations.DeleteModel(
name="HistoricalRide",
),
migrations.DeleteModel(
name="HistoricalRideModel",
),
]

View File

@@ -4,7 +4,7 @@ import sys
import django
from django.conf import settings
from django.test.runner import DiscoverRunner
import coverage
import coverage # type: ignore
import unittest
def setup_django():

View File

@@ -68,7 +68,7 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"core.middleware.setup_pghistory_context", # Add history context tracking
"core.middleware.PgHistoryContextMiddleware", # Add history context tracking
"allauth.account.middleware.AccountMiddleware",
"django.middleware.cache.FetchFromCacheMiddleware",
"simple_history.middleware.HistoryRequestMiddleware",