Refactor test utilities and enhance ASGI settings

- Cleaned up and standardized assertions in ApiTestMixin for API response validation.
- Updated ASGI settings to use os.environ for setting the DJANGO_SETTINGS_MODULE.
- Removed unused imports and improved formatting in settings.py.
- Refactored URL patterns in urls.py for better readability and organization.
- Enhanced view functions in views.py for consistency and clarity.
- Added .flake8 configuration for linting and style enforcement.
- Introduced type stubs for django-environ to improve type checking with Pylance.
This commit is contained in:
pacnpal
2025-08-20 19:51:59 -04:00
parent 69c07d1381
commit 66ed4347a9
230 changed files with 15094 additions and 11578 deletions

View File

@@ -1,3 +1,4 @@
from parks.models import Park, ParkArea
from django import forms
from django.forms import ModelChoiceField
from django.urls import reverse_lazy
@@ -6,7 +7,6 @@ from .models.rides import Ride, RideModel
Manufacturer = Company
Designer = Company
from parks.models import Park, ParkArea
class RideForm(forms.ModelForm):
@@ -15,7 +15,10 @@ class RideForm(forms.ModelForm):
required=True,
widget=forms.TextInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Search for a park...",
"hx-get": "/parks/search/",
"hx-trigger": "click, input delay:200ms",
@@ -25,13 +28,16 @@ class RideForm(forms.ModelForm):
}
),
)
manufacturer_search = forms.CharField(
label="Manufacturer",
required=False,
widget=forms.TextInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Search for a manufacturer...",
"hx-get": reverse_lazy("rides:search_companies"),
"hx-trigger": "click, input delay:200ms",
@@ -41,13 +47,16 @@ class RideForm(forms.ModelForm):
}
),
)
designer_search = forms.CharField(
label="Designer",
required=False,
widget=forms.TextInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Search for a designer...",
"hx-get": reverse_lazy("rides:search_companies"),
"hx-trigger": "click, input delay:200ms",
@@ -63,7 +72,10 @@ class RideForm(forms.ModelForm):
required=False,
widget=forms.TextInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Search for a ride model...",
"hx-get": reverse_lazy("rides:search_ride_models"),
"hx-trigger": "click, input delay:200ms",
@@ -79,37 +91,40 @@ class RideForm(forms.ModelForm):
queryset=Park.objects.all(),
required=True,
label="",
widget=forms.HiddenInput()
widget=forms.HiddenInput(),
)
manufacturer = forms.ModelChoiceField(
queryset=Manufacturer.objects.all(),
required=False,
label="",
widget=forms.HiddenInput()
widget=forms.HiddenInput(),
)
designer = forms.ModelChoiceField(
queryset=Designer.objects.all(),
required=False,
label="",
widget=forms.HiddenInput()
widget=forms.HiddenInput(),
)
ride_model = forms.ModelChoiceField(
queryset=RideModel.objects.all(),
required=False,
label="",
widget=forms.HiddenInput()
widget=forms.HiddenInput(),
)
park_area = ModelChoiceField(
queryset=ParkArea.objects.none(),
required=False,
widget=forms.Select(
attrs={
"class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"placeholder": "Select an area within the park..."
"class": (
"w-full border-gray-300 rounded-lg form-select "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Select an area within the park...",
}
),
)
@@ -136,91 +151,127 @@ class RideForm(forms.ModelForm):
widgets = {
"name": forms.TextInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"placeholder": "Official name of the ride"
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Official name of the ride",
}
),
"category": forms.Select(
attrs={
"class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-select "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"hx-get": reverse_lazy("rides:coaster_fields"),
"hx-target": "#coaster-fields",
"hx-trigger": "change",
"hx-include": "this",
"hx-swap": "innerHTML"
"hx-swap": "innerHTML",
}
),
"status": forms.Select(
attrs={
"class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-select "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Current operational status",
"x-model": "status",
"@change": "handleStatusChange"
"@change": "handleStatusChange",
}
),
"post_closing_status": forms.Select(
attrs={
"class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-select "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Status after closing",
"x-show": "status === 'CLOSING'"
"x-show": "status === 'CLOSING'",
}
),
"opening_date": forms.DateInput(
attrs={
"type": "date",
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"placeholder": "Date when ride first opened"
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Date when ride first opened",
}
),
"closing_date": forms.DateInput(
attrs={
"type": "date",
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Date when ride will close",
"x-show": "['CLOSING', 'SBNO', 'CLOSED_PERM', 'DEMOLISHED', 'RELOCATED'].includes(status)",
":required": "status === 'CLOSING'"
":required": "status === 'CLOSING'",
}
),
"status_since": forms.DateInput(
attrs={
"type": "date",
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"placeholder": "Date when current status took effect"
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Date when current status took effect",
}
),
"min_height_in": forms.NumberInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"min": "0",
"placeholder": "Minimum height requirement in inches"
"placeholder": "Minimum height requirement in inches",
}
),
"max_height_in": forms.NumberInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"min": "0",
"placeholder": "Maximum height limit in inches (if applicable)"
"placeholder": "Maximum height limit in inches (if applicable)",
}
),
"capacity_per_hour": forms.NumberInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"min": "0",
"placeholder": "Theoretical hourly ride capacity"
"placeholder": "Theoretical hourly ride capacity",
}
),
"ride_duration_seconds": forms.NumberInput(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"min": "0",
"placeholder": "Total duration of one ride cycle in seconds"
"placeholder": "Total duration of one ride cycle in seconds",
}
),
"description": forms.Textarea(
attrs={
"rows": 4,
"class": "w-full border-gray-300 rounded-lg form-textarea dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"placeholder": "General description and notable features of the ride"
"class": (
"w-full border-gray-300 rounded-lg form-textarea "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "General description and notable features of the ride",
}
),
}
@@ -228,10 +279,10 @@ class RideForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
park = kwargs.pop("park", None)
super().__init__(*args, **kwargs)
# Make category required
self.fields['category'].required = True
self.fields["category"].required = True
# Clear any default values for date fields
self.fields["opening_date"].initial = None
self.fields["closing_date"].initial = None
@@ -239,13 +290,27 @@ class RideForm(forms.ModelForm):
# Move fields to the beginning in desired order
field_order = [
"park_search", "park", "park_area",
"name", "manufacturer_search", "manufacturer",
"designer_search", "designer", "ride_model_search",
"ride_model", "category", "status",
"post_closing_status", "opening_date", "closing_date", "status_since",
"min_height_in", "max_height_in", "capacity_per_hour",
"ride_duration_seconds", "description"
"park_search",
"park",
"park_area",
"name",
"manufacturer_search",
"manufacturer",
"designer_search",
"designer",
"ride_model_search",
"ride_model",
"category",
"status",
"post_closing_status",
"opening_date",
"closing_date",
"status_since",
"min_height_in",
"max_height_in",
"capacity_per_hour",
"ride_duration_seconds",
"description",
]
self.order_fields(field_order)
@@ -260,23 +325,30 @@ class RideForm(forms.ModelForm):
required=False,
widget=forms.Select(
attrs={
"class": "w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"placeholder": "Select an area within the park..."
"class": (
"w-full border-gray-300 rounded-lg form-select "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"placeholder": "Select an area within the park...",
}
),
)
else:
# If no park provided, show park search and disable park_area until park is selected
# If no park provided, show park search and disable park_area until
# park is selected
self.fields["park_area"].widget.attrs["disabled"] = True
# Initialize park search with current park name if editing
if self.instance and self.instance.pk and self.instance.park:
self.fields["park_search"].initial = self.instance.park.name
self.fields["park"].initial = self.instance.park
# Initialize manufacturer, designer, and ride model search fields if editing
# Initialize manufacturer, designer, and ride model search fields if
# editing
if self.instance and self.instance.pk:
if self.instance.manufacturer:
self.fields["manufacturer_search"].initial = self.instance.manufacturer.name
self.fields["manufacturer_search"].initial = (
self.instance.manufacturer.name
)
self.fields["manufacturer"].initial = self.instance.manufacturer
if self.instance.designer:
self.fields["designer_search"].initial = self.instance.designer.name
@@ -288,13 +360,17 @@ class RideForm(forms.ModelForm):
class RideSearchForm(forms.Form):
"""Form for searching rides with HTMX autocomplete."""
ride = forms.ModelChoiceField(
queryset=Ride.objects.all(),
label="Find a ride",
required=False,
widget=forms.Select(
attrs={
"class": "w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white",
"class": (
"w-full border-gray-300 rounded-lg form-input "
"dark:border-gray-600 dark:bg-gray-700 dark:text-white"
),
"hx-get": reverse_lazy("rides:search"),
"hx-trigger": "change",
"hx-target": "#ride-search-results",