from django.views.generic import DetailView, ListView, CreateView, UpdateView from django.shortcuts import get_object_or_404 from django.urls import reverse from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.contenttypes.models import ContentType from django.contrib import messages from django.http import HttpResponseRedirect, Http404, JsonResponse from django.db.models import Count, Sum, Q from .models import Company, Manufacturer from .forms import CompanyForm, ManufacturerForm from rides.models import Ride from parks.models import Park from location.models import Location from core.views import SlugRedirectMixin from moderation.mixins import EditSubmissionMixin, PhotoSubmissionMixin, HistoryMixin from moderation.models import EditSubmission # List Views class CompanyListView(ListView): model = Company template_name = 'companies/company_list.html' context_object_name = 'companies' paginate_by = 12 def get_queryset(self): queryset = Company.objects.all() # Filter by country if specified country = self.request.GET.get('country') if country: # Get companies that have locations in the specified country company_ids = Location.objects.filter( content_type=ContentType.objects.get_for_model(Company), country__iexact=country ).values_list('object_id', flat=True) queryset = queryset.filter(id__in=company_ids) # Search by name if specified search = self.request.GET.get('search') if search: queryset = queryset.filter(name__icontains=search) return queryset.order_by('name') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Add filter values to context context['country'] = self.request.GET.get('country', '') context['search'] = self.request.GET.get('search', '') return context class ManufacturerListView(ListView): model = Manufacturer template_name = 'companies/manufacturer_list.html' context_object_name = 'manufacturers' paginate_by = 12 def get_queryset(self): queryset = Manufacturer.objects.all() # Filter by country if specified country = self.request.GET.get('country') if country: # Get manufacturers that have locations in the specified country manufacturer_ids = Location.objects.filter( content_type=ContentType.objects.get_for_model(Manufacturer), country__iexact=country ).values_list('object_id', flat=True) queryset = queryset.filter(id__in=manufacturer_ids) # Search by name if specified search = self.request.GET.get('search') if search: queryset = queryset.filter(name__icontains=search) return queryset.order_by('name') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Add stats for filtering context['total_manufacturers'] = self.model.objects.count() context['total_rides'] = Ride.objects.filter( manufacturer__isnull=False ).count() context['total_roller_coasters'] = Ride.objects.filter( manufacturer__isnull=False, category='ROLLER_COASTER' ).count() # Add filter values to context context['country'] = self.request.GET.get('country', '') context['search'] = self.request.GET.get('search', '') return context # Detail Views class CompanyDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixin, HistoryMixin, DetailView): model = Company template_name = 'companies/company_detail.html' context_object_name = 'company' def get_object(self, queryset=None): if queryset is None: queryset = self.get_queryset() slug = self.kwargs.get(self.slug_url_kwarg) try: # Try to get by current or historical slug return self.model.get_by_slug(slug)[0] except self.model.DoesNotExist: raise Http404(f"No {self.model._meta.verbose_name} found matching the query") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) parks = Park.objects.filter( owner=self.object ).select_related('owner') context['parks'] = parks context['total_rides'] = Ride.objects.filter(park__in=parks).count() return context def get_redirect_url_pattern(self): return 'companies:company_detail' def post(self, request, *args, **kwargs): """Handle POST requests for photos and edits""" if request.FILES: # Handle photo submission return self.handle_photo_submission(request) # Handle edit submission return super().post(request, *args, **kwargs) class ManufacturerDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixin, HistoryMixin, DetailView): model = Manufacturer template_name = 'companies/manufacturer_detail.html' context_object_name = 'manufacturer' def get_object(self, queryset=None): if queryset is None: queryset = self.get_queryset() slug = self.kwargs.get(self.slug_url_kwarg) try: # Try to get by current or historical slug return self.model.get_by_slug(slug)[0] except self.model.DoesNotExist: raise Http404(f"No {self.model._meta.verbose_name} found matching the query") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) rides = Ride.objects.filter( manufacturer=self.object ).select_related('park', 'coaster_stats') context['rides'] = rides context['coaster_count'] = rides.filter(category='ROLLER_COASTER').count() context['parks_count'] = rides.values('park').distinct().count() return context def get_redirect_url_pattern(self): return 'companies:manufacturer_detail' def post(self, request, *args, **kwargs): """Handle POST requests for photos and edits""" if request.FILES: # Handle photo submission return self.handle_photo_submission(request) # Handle edit submission return super().post(request, *args, **kwargs) # Create Views class CompanyCreateView(LoginRequiredMixin, CreateView): model = Company form_class = CompanyForm template_name = 'companies/company_form.html' def form_valid(self, form): cleaned_data = form.cleaned_data.copy() # Create submission record submission = EditSubmission.objects.create( user=self.request.user, content_type=ContentType.objects.get_for_model(Company), submission_type='CREATE', changes=cleaned_data, 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 company submission has been sent for review') return HttpResponseRedirect(reverse('companies:company_list')) def get_success_url(self): return reverse('companies:company_detail', kwargs={'slug': self.object.slug}) class ManufacturerCreateView(LoginRequiredMixin, CreateView): model = Manufacturer form_class = ManufacturerForm template_name = 'companies/manufacturer_form.html' def form_valid(self, form): cleaned_data = form.cleaned_data.copy() # Create submission record submission = EditSubmission.objects.create( user=self.request.user, content_type=ContentType.objects.get_for_model(Manufacturer), submission_type='CREATE', changes=cleaned_data, 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 manufacturer submission has been sent for review') return HttpResponseRedirect(reverse('companies:manufacturer_list')) def get_success_url(self): return reverse('companies:manufacturer_detail', kwargs={'slug': self.object.slug}) # Update Views class CompanyUpdateView(LoginRequiredMixin, UpdateView): model = Company form_class = CompanyForm template_name = 'companies/company_form.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['is_edit'] = True return context def form_valid(self, form): cleaned_data = form.cleaned_data.copy() # Create submission record submission = EditSubmission.objects.create( user=self.request.user, content_type=ContentType.objects.get_for_model(Company), object_id=self.object.id, submission_type='EDIT', changes=cleaned_data, 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('companies:company_detail', kwargs={'slug': self.object.slug})) def get_success_url(self): return reverse('companies:company_detail', kwargs={'slug': self.object.slug}) class ManufacturerUpdateView(LoginRequiredMixin, UpdateView): model = Manufacturer form_class = ManufacturerForm template_name = 'companies/manufacturer_form.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['is_edit'] = True return context def form_valid(self, form): cleaned_data = form.cleaned_data.copy() # Create submission record submission = EditSubmission.objects.create( user=self.request.user, content_type=ContentType.objects.get_for_model(Manufacturer), object_id=self.object.id, submission_type='EDIT', changes=cleaned_data, 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('companies:manufacturer_detail', kwargs={'slug': self.object.slug})) def get_success_url(self): return reverse('companies:manufacturer_detail', kwargs={'slug': self.object.slug})