Implement entity submission services for ThrillWiki

- Added BaseEntitySubmissionService as an abstract base for entity submissions.
- Created specific submission services for entities: Park, Ride, Company, RideModel.
- Implemented create, update, and delete functionalities with moderation workflow.
- Enhanced logging and validation for required fields.
- Addressed foreign key handling and special field processing for each entity type.
- Noted existing issues with JSONField usage in Company submissions.
This commit is contained in:
pacnpal
2025-11-08 22:23:41 -05:00
parent 9122320e7e
commit 2884bc23ce
29 changed files with 8699 additions and 330 deletions

View File

@@ -16,6 +16,58 @@ import pghistory
from apps.core.models import VersionedModel, BaseModel
@pghistory.track()
class CompanyType(BaseModel):
"""
Lookup table for company types (manufacturer, operator, designer, etc.).
This replaces the previous JSONField approach to maintain proper relational integrity.
"""
TYPE_CHOICES = [
('manufacturer', 'Manufacturer'),
('operator', 'Operator'),
('designer', 'Designer'),
('supplier', 'Supplier'),
('contractor', 'Contractor'),
]
code = models.CharField(
max_length=50,
unique=True,
choices=TYPE_CHOICES,
db_index=True,
help_text="Unique code identifier for the company type"
)
name = models.CharField(
max_length=100,
help_text="Display name for the company type"
)
description = models.TextField(
blank=True,
help_text="Description of what this company type represents"
)
company_count = models.IntegerField(
default=0,
help_text="Cached count of companies with this type"
)
class Meta:
db_table = 'company_types'
verbose_name = 'Company Type'
verbose_name_plural = 'Company Types'
ordering = ['name']
def __str__(self):
return self.name
def update_company_count(self):
"""Update cached company count."""
self.company_count = self.companies.count()
self.save(update_fields=['company_count'])
# Conditionally import GIS models only if using PostGIS backend
# This allows migrations to run on SQLite during local development
_using_postgis = (
@@ -61,10 +113,12 @@ class Company(VersionedModel):
help_text="Company description and history"
)
# Company Types (can be multiple)
company_types = models.JSONField(
default=list,
help_text="List of company types (manufacturer, operator, etc.)"
# Company Types (M2M relationship - replaces old JSONField)
types = models.ManyToManyField(
'CompanyType',
related_name='companies',
blank=True,
help_text="Types of company (manufacturer, operator, etc.)"
)
# Location
@@ -177,6 +231,25 @@ class Company(VersionedModel):
self.ride_count = self.manufactured_rides.count()
self.save(update_fields=['park_count', 'ride_count'])
@property
def company_types(self):
"""
Backward-compatible property that returns list of type codes.
This maintains API compatibility with the old JSONField approach.
Returns: List of type codes (e.g., ['manufacturer', 'operator'])
"""
return list(self.types.values_list('code', flat=True))
@property
def type_names(self):
"""
Get display names for company types.
Returns: List of type display names (e.g., ['Manufacturer', 'Operator'])
"""
return list(self.types.values_list('name', flat=True))
def get_photos(self, photo_type=None, approved_only=True):
"""Get photos for this company."""
from apps.media.services import PhotoService