mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-30 08:27:00 -05:00
feat: Implement MFA authentication, add ride statistics model, and update various services, APIs, and tests across the application.
This commit is contained in:
@@ -1,41 +1,41 @@
|
||||
from .querysets import get_base_park_queryset
|
||||
from apps.core.mixins import HTMXFilterableMixin
|
||||
from .models.location import ParkLocation
|
||||
from .models.media import ParkPhoto
|
||||
from apps.moderation.mixins import (
|
||||
EditSubmissionMixin,
|
||||
PhotoSubmissionMixin,
|
||||
HistoryMixin,
|
||||
)
|
||||
from apps.core.views.views import SlugRedirectMixin
|
||||
from .filters import ParkFilter
|
||||
from .forms import ParkForm
|
||||
from .models import Park, ParkArea, ParkReview as Review
|
||||
from .services import ParkFilterService, ParkService
|
||||
from django.http import (
|
||||
HttpResponseRedirect,
|
||||
HttpResponse,
|
||||
HttpRequest,
|
||||
JsonResponse,
|
||||
)
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db.models import QuerySet
|
||||
from django.urls import reverse
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from decimal import InvalidOperation
|
||||
from django.views.generic import DetailView, ListView, CreateView, UpdateView
|
||||
import requests
|
||||
from decimal import Decimal, ROUND_DOWN
|
||||
from typing import Any, Optional, cast, Literal, Dict
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import logging
|
||||
from decimal import ROUND_DOWN, Decimal, InvalidOperation
|
||||
from typing import Any, Literal, cast
|
||||
|
||||
from apps.core.logging import log_exception, log_business_event
|
||||
import requests
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import QuerySet
|
||||
from django.http import (
|
||||
HttpRequest,
|
||||
HttpResponse,
|
||||
HttpResponseRedirect,
|
||||
JsonResponse,
|
||||
)
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.views.generic import CreateView, DetailView, ListView, UpdateView
|
||||
|
||||
from apps.core.logging import log_business_event, log_exception
|
||||
from apps.core.mixins import HTMXFilterableMixin
|
||||
from apps.core.views.views import SlugRedirectMixin
|
||||
from apps.moderation.mixins import (
|
||||
EditSubmissionMixin,
|
||||
HistoryMixin,
|
||||
PhotoSubmissionMixin,
|
||||
)
|
||||
|
||||
from .filters import ParkFilter
|
||||
from .forms import ParkForm
|
||||
from .models import Park, ParkArea
|
||||
from .models import ParkReview as Review
|
||||
from .querysets import get_base_park_queryset
|
||||
from .services import ParkFilterService, ParkService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -364,7 +364,7 @@ class ParkListView(HTMXFilterableMixin, ListView):
|
||||
"search_query": self.request.GET.get("search", ""),
|
||||
}
|
||||
|
||||
def _get_clean_filter_params(self) -> Dict[str, Any]:
|
||||
def _get_clean_filter_params(self) -> dict[str, Any]:
|
||||
"""Extract and clean filter parameters from request."""
|
||||
filter_params = {}
|
||||
|
||||
@@ -391,7 +391,7 @@ class ParkListView(HTMXFilterableMixin, ListView):
|
||||
|
||||
return {k: v for k, v in filter_params.items() if v is not None}
|
||||
|
||||
def _clean_filter_value(self, param: str, value: str) -> Optional[Any]:
|
||||
def _clean_filter_value(self, param: str, value: str) -> Any | None:
|
||||
"""Clean and validate a single filter value."""
|
||||
if param in ("has_coasters", "big_parks_only"):
|
||||
# Boolean filters
|
||||
@@ -413,7 +413,7 @@ class ParkListView(HTMXFilterableMixin, ListView):
|
||||
# String filters
|
||||
return value.strip()
|
||||
|
||||
def _build_filter_query_string(self, filter_params: Dict[str, Any]) -> str:
|
||||
def _build_filter_query_string(self, filter_params: dict[str, Any]) -> str:
|
||||
"""Build query string from filter parameters."""
|
||||
from urllib.parse import urlencode
|
||||
|
||||
@@ -428,8 +428,8 @@ class ParkListView(HTMXFilterableMixin, ListView):
|
||||
return urlencode(url_params)
|
||||
|
||||
def _get_pagination_urls(
|
||||
self, page_obj, filter_params: Dict[str, Any]
|
||||
) -> Dict[str, str]:
|
||||
self, page_obj, filter_params: dict[str, Any]
|
||||
) -> dict[str, str]:
|
||||
"""Generate pagination URLs that preserve filter state."""
|
||||
|
||||
base_query = self._build_filter_query_string(filter_params)
|
||||
@@ -841,10 +841,8 @@ def htmx_save_trip(request: HttpRequest) -> HttpResponse:
|
||||
|
||||
trip = Trip.objects.create(owner=request.user, name=name)
|
||||
# attempt to associate parks if the Trip model supports it
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
trip.parks.set([p.id for p in parks])
|
||||
except Exception:
|
||||
pass
|
||||
trips = list(
|
||||
Trip.objects.filter(owner=request.user).order_by("-created_at")[:10]
|
||||
)
|
||||
@@ -1133,7 +1131,7 @@ class ParkDetailView(
|
||||
template_name = "parks/park_detail.html"
|
||||
context_object_name = "park"
|
||||
|
||||
def get_object(self, queryset: Optional[QuerySet[Park]] = None) -> Park:
|
||||
def get_object(self, queryset: QuerySet[Park] | None = None) -> Park:
|
||||
if queryset is None:
|
||||
queryset = self.get_queryset()
|
||||
slug = self.kwargs.get(self.slug_url_kwarg)
|
||||
@@ -1184,7 +1182,7 @@ class ParkAreaDetailView(
|
||||
context_object_name = "area"
|
||||
slug_url_kwarg = "area_slug"
|
||||
|
||||
def get_object(self, queryset: Optional[QuerySet[ParkArea]] = None) -> ParkArea:
|
||||
def get_object(self, queryset: QuerySet[ParkArea] | None = None) -> ParkArea:
|
||||
if queryset is None:
|
||||
queryset = self.get_queryset()
|
||||
park_slug = self.kwargs.get("park_slug")
|
||||
@@ -1217,9 +1215,10 @@ class OperatorListView(ListView):
|
||||
|
||||
def get_queryset(self):
|
||||
"""Get companies that are operators with optimized query"""
|
||||
from .models.companies import Company
|
||||
from django.db.models import Count
|
||||
|
||||
from .models.companies import Company
|
||||
|
||||
return (
|
||||
Company.objects.filter(roles__contains=["OPERATOR"])
|
||||
.annotate(park_count=Count("operated_parks"))
|
||||
|
||||
Reference in New Issue
Block a user