mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 04:31:09 -05:00
315 lines
11 KiB
Python
315 lines
11 KiB
Python
from django.views.generic import DetailView, ListView, CreateView, UpdateView
|
|
from django.shortcuts import get_object_or_404, render
|
|
from django.core.serializers.json import DjangoJSONEncoder
|
|
from django.urls import reverse
|
|
from django.db.models import Q
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.contrib import messages
|
|
from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
|
|
from .models import Park, ParkArea
|
|
from .forms import ParkForm
|
|
from rides.models import Ride
|
|
from core.views import SlugRedirectMixin
|
|
from moderation.mixins import EditSubmissionMixin, PhotoSubmissionMixin, HistoryMixin
|
|
from moderation.models import EditSubmission
|
|
from cities_light.models import Country, Region, City
|
|
|
|
|
|
def get_countries(request):
|
|
query = request.GET.get("q", "")
|
|
filter_parks = request.GET.get("filter_parks", "false") == "true"
|
|
|
|
# Base query
|
|
countries = Country.objects.filter(name__icontains=query)
|
|
|
|
# Only filter by parks if explicitly requested
|
|
if filter_parks:
|
|
countries = countries.filter(park__isnull=False)
|
|
|
|
countries = countries.distinct().values("id", "name")[:10]
|
|
return JsonResponse(list(countries), safe=False)
|
|
|
|
|
|
def get_regions(request):
|
|
query = request.GET.get("q", "")
|
|
country = request.GET.get("country", "")
|
|
filter_parks = request.GET.get("filter_parks", "false") == "true"
|
|
|
|
if not country:
|
|
return JsonResponse([], safe=False)
|
|
|
|
# Base query
|
|
regions = Region.objects.filter(
|
|
Q(name__icontains=query) | Q(alternate_names__icontains=query),
|
|
country__name__iexact=country,
|
|
)
|
|
|
|
# Only filter by parks if explicitly requested
|
|
if filter_parks:
|
|
regions = regions.filter(park__isnull=False)
|
|
|
|
regions = regions.distinct().values("id", "name")[:10]
|
|
return JsonResponse(list(regions), safe=False)
|
|
|
|
|
|
def get_cities(request):
|
|
query = request.GET.get("q", "")
|
|
region = request.GET.get("region", "")
|
|
country = request.GET.get("country", "")
|
|
filter_parks = request.GET.get("filter_parks", "false") == "true"
|
|
|
|
if not region or not country:
|
|
return JsonResponse([], safe=False)
|
|
|
|
# Base query
|
|
cities = City.objects.filter(
|
|
Q(name__icontains=query) | Q(alternate_names__icontains=query),
|
|
region__name__iexact=region,
|
|
region__country__name__iexact=country,
|
|
)
|
|
|
|
# Only filter by parks if explicitly requested
|
|
if filter_parks:
|
|
cities = cities.filter(park__isnull=False)
|
|
|
|
cities = cities.distinct().values("id", "name")[:10]
|
|
return JsonResponse(list(cities), safe=False)
|
|
|
|
|
|
class ParkCreateView(LoginRequiredMixin, CreateView):
|
|
model = Park
|
|
form_class = ParkForm
|
|
template_name = "parks/park_form.html"
|
|
|
|
def prepare_changes_data(self, cleaned_data):
|
|
data = cleaned_data.copy()
|
|
# Convert model instances to IDs for JSON serialization
|
|
if data.get("owner"):
|
|
data["owner"] = data["owner"].id
|
|
if data.get("country"):
|
|
data["country"] = data["country"].id
|
|
if data.get("region"):
|
|
data["region"] = data["region"].id
|
|
if data.get("city"):
|
|
data["city"] = data["city"].id
|
|
# Convert dates to ISO format strings
|
|
if data.get("opening_date"):
|
|
data["opening_date"] = data["opening_date"].isoformat()
|
|
if data.get("closing_date"):
|
|
data["closing_date"] = data["closing_date"].isoformat()
|
|
return data
|
|
|
|
def form_valid(self, form):
|
|
changes = self.prepare_changes_data(form.cleaned_data)
|
|
|
|
# Create submission record
|
|
submission = EditSubmission.objects.create(
|
|
user=self.request.user,
|
|
content_type=ContentType.objects.get_for_model(Park),
|
|
submission_type="CREATE",
|
|
changes=changes,
|
|
reason=self.request.POST.get("reason", ""),
|
|
source=self.request.POST.get("source", ""),
|
|
)
|
|
|
|
# If user is moderator or above, auto-approve
|
|
if self.request.user.role in ["MODERATOR", "ADMIN", "SUPERUSER"]:
|
|
self.object = form.save()
|
|
submission.object_id = self.object.id
|
|
submission.status = "APPROVED"
|
|
submission.handled_by = self.request.user
|
|
submission.save()
|
|
messages.success(self.request, f"Successfully created {self.object.name}")
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
messages.success(self.request, "Your park submission has been sent for review")
|
|
return HttpResponseRedirect(reverse("parks:park_list"))
|
|
|
|
def get_success_url(self):
|
|
return reverse("parks:park_detail", kwargs={"slug": self.object.slug})
|
|
|
|
|
|
class ParkUpdateView(LoginRequiredMixin, UpdateView):
|
|
model = Park
|
|
form_class = ParkForm
|
|
template_name = "parks/park_form.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["is_edit"] = True
|
|
return context
|
|
|
|
def prepare_changes_data(self, cleaned_data):
|
|
data = cleaned_data.copy()
|
|
# Convert model instances to IDs for JSON serialization
|
|
if data.get("owner"):
|
|
data["owner"] = data["owner"].id
|
|
if data.get("country"):
|
|
data["country"] = data["country"].id
|
|
if data.get("region"):
|
|
data["region"] = data["region"].id
|
|
if data.get("city"):
|
|
data["city"] = data["city"].id
|
|
# Convert dates to ISO format strings
|
|
if data.get("opening_date"):
|
|
data["opening_date"] = data["opening_date"].isoformat()
|
|
if data.get("closing_date"):
|
|
data["closing_date"] = data["closing_date"].isoformat()
|
|
return data
|
|
|
|
def form_valid(self, form):
|
|
changes = self.prepare_changes_data(form.cleaned_data)
|
|
|
|
# Create submission record
|
|
submission = EditSubmission.objects.create(
|
|
user=self.request.user,
|
|
content_type=ContentType.objects.get_for_model(Park),
|
|
object_id=self.object.id,
|
|
submission_type="EDIT",
|
|
changes=changes,
|
|
reason=self.request.POST.get("reason", ""),
|
|
source=self.request.POST.get("source", ""),
|
|
)
|
|
|
|
# If user is moderator or above, auto-approve
|
|
if self.request.user.role in ["MODERATOR", "ADMIN", "SUPERUSER"]:
|
|
self.object = form.save()
|
|
submission.status = "APPROVED"
|
|
submission.handled_by = self.request.user
|
|
submission.save()
|
|
messages.success(self.request, f"Successfully updated {self.object.name}")
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
messages.success(
|
|
self.request,
|
|
f"Your changes to {self.object.name} have been sent for review",
|
|
)
|
|
return HttpResponseRedirect(
|
|
reverse("parks:park_detail", kwargs={"slug": self.object.slug})
|
|
)
|
|
|
|
def get_success_url(self):
|
|
return reverse("parks:park_detail", kwargs={"slug": self.object.slug})
|
|
|
|
|
|
class ParkDetailView(
|
|
SlugRedirectMixin,
|
|
EditSubmissionMixin,
|
|
PhotoSubmissionMixin,
|
|
HistoryMixin,
|
|
DetailView,
|
|
):
|
|
model = Park
|
|
template_name = "parks/park_detail.html"
|
|
context_object_name = "park"
|
|
|
|
def get_object(self, queryset=None):
|
|
if queryset is None:
|
|
queryset = self.get_queryset()
|
|
slug = self.kwargs.get(self.slug_url_kwarg)
|
|
# Try to get by current or historical slug
|
|
return self.model.get_by_slug(slug)[0]
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["rides"] = Ride.objects.filter(park=self.object).select_related(
|
|
"coaster_stats"
|
|
)
|
|
context["areas"] = ParkArea.objects.filter(park=self.object)
|
|
return context
|
|
|
|
def get_redirect_url_pattern(self):
|
|
return "parks:park_detail"
|
|
|
|
|
|
class ParkAreaDetailView(
|
|
SlugRedirectMixin,
|
|
EditSubmissionMixin,
|
|
PhotoSubmissionMixin,
|
|
HistoryMixin,
|
|
DetailView,
|
|
):
|
|
model = ParkArea
|
|
template_name = "parks/area_detail.html"
|
|
context_object_name = "area"
|
|
slug_url_kwarg = "area_slug"
|
|
|
|
def get_object(self, queryset=None):
|
|
if queryset is None:
|
|
queryset = self.get_queryset()
|
|
park_slug = self.kwargs.get("park_slug")
|
|
area_slug = self.kwargs.get("area_slug")
|
|
# Try to get by current or historical slug
|
|
obj, is_old_slug = self.model.get_by_slug(area_slug)
|
|
if obj.park.slug != park_slug:
|
|
raise self.model.DoesNotExist("Park slug doesn't match")
|
|
return obj
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["rides"] = Ride.objects.filter(area=self.object).select_related(
|
|
"coaster_stats"
|
|
)
|
|
return context
|
|
|
|
def get_redirect_url_pattern(self):
|
|
return "parks:park_detail"
|
|
|
|
def get_redirect_url_kwargs(self):
|
|
return {"park_slug": self.object.park.slug, "area_slug": self.object.slug}
|
|
|
|
|
|
class ParkListView(ListView):
|
|
model = Park
|
|
template_name = "parks/park_list.html"
|
|
context_object_name = "parks"
|
|
|
|
def get_queryset(self):
|
|
queryset = Park.objects.select_related(
|
|
"owner", "country", "region", "city"
|
|
).prefetch_related("photos", "rides")
|
|
|
|
search = self.request.GET.get("search", "").strip()
|
|
country = self.request.GET.get("country", "").strip()
|
|
region = self.request.GET.get("region", "").strip()
|
|
city = self.request.GET.get("city", "").strip()
|
|
statuses = self.request.GET.getlist("status")
|
|
|
|
if search:
|
|
queryset = queryset.filter(
|
|
Q(name__icontains=search) | Q(location__icontains=search)
|
|
)
|
|
|
|
if country:
|
|
queryset = queryset.filter(country__name__icontains=country)
|
|
|
|
if region:
|
|
queryset = queryset.filter(region__name__icontains=region)
|
|
|
|
if city:
|
|
queryset = queryset.filter(city__name__icontains=city)
|
|
|
|
if statuses:
|
|
queryset = queryset.filter(status__in=statuses)
|
|
|
|
return queryset
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["current_filters"] = {
|
|
"search": self.request.GET.get("search", ""),
|
|
"country": self.request.GET.get("country", ""),
|
|
"region": self.request.GET.get("region", ""),
|
|
"city": self.request.GET.get("city", ""),
|
|
"statuses": self.request.GET.getlist("status"),
|
|
}
|
|
return context
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
# Check if this is an HTMX request
|
|
if request.htmx:
|
|
# If it is, return just the parks list partial
|
|
self.template_name = "parks/partials/park_list.html"
|
|
return super().get(request, *args, **kwargs)
|