This repository has been archived on 2025-11-04. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
csmb-housewars/housewars/views.py

98 lines
3.7 KiB
Python

from django.contrib import messages
from django.db.models import Count, F, Q, Subquery, OuterRef
from django.db.models.functions import Coalesce
from django.shortcuts import redirect
from django.urls import reverse
from django.views.generic import CreateView
from formtools.wizard.views import SessionWizardView
from .forms import ActivityForm, PointsEntryForm, UserEntryForm
from .models import Activity, Quota, PointsEntry, UserEntry
FORMS = [("user", UserEntryForm),
("activity", ActivityForm)]
TEMPLATES = {"user": "housewars/entry_form.html",
"activity": "housewars/activity_form.html"}
class EntryCreateView(SessionWizardView):
form_list = FORMS
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
def get_form(self, step=None, data=None, files=None):
form = super().get_form(step, data, files)
if step == 'activity':
cd = self.storage.get_step_data('user')
# Retrieve custom quotas for house activities
quota = Quota.objects.filter(
house=cd.get('user-house'), activity=OuterRef('id')).values('quota')
# Set quota to custom quota or default, then set count to the total signups for each activity. Filter where quota is less than house signups.
filtered1 = Activity.objects.annotate(final_quota=Coalesce(Subquery(quota[:1]), F('default_quota'))).annotate(count=Count(
'activity1', filter=Q(activity1__house=cd.get('user-house')))).filter(final_quota__gt=F('count'))
filtered2 = Activity.objects.annotate(final_quota=Coalesce(Subquery(quota[:1]), F('default_quota'))).annotate(count=Count(
'activity2', filter=Q(activity2__house=cd.get('user-house')))).filter(final_quota__gt=F('count'), time=30)
# Render filtered as choices in activity select step
form.fields['activity1'].queryset = filtered1
form.fields['activity2'].queryset = filtered2
return form
def done(self, form_list, **kwargs):
cleaned_data = self.get_all_cleaned_data()
UserEntry.objects.create(**cleaned_data)
activity1 = cleaned_data['activity1']
activity1_room = activity1.room_number
activity2 = cleaned_data['activity2']
activity2_room = activity2.room_number
# Build the response string.
a1_string = f'You are in {activity1}'
if (activity1_room != None):
a1_string += f' in Room {activity1_room}'
if (hasattr(activity1, 'teacher')):
activity1_teacher = activity1.teacher
a1_string += f' with {activity1_teacher}.'
else:
a1_string += '.'
a2_string = ''
if (activity2 != None):
a2_string = f'You are in {activity2}'
if (activity2_room != None):
a2_string += f' in Room {activity2_room}'
if (hasattr(activity2, 'teacher')):
activity2_teacher = activity2.teacher.last_name
a2_string += f' with {activity2_teacher}.'
else:
a2_string += '.'
messages.success(self.request, 'Your signup has been submitted.')
messages.success(self.request, a1_string)
messages.success(self.request, a2_string)
return redirect('housewars:signup')
def get_success_url(self):
return reverse('housewars:signup')
class PointsEntryCreateView(CreateView):
model = PointsEntry
form_class = PointsEntryForm
def form_valid(self, form):
messages.success(self.request, 'Your points entry has been submitted.')
return super().form_valid(form)
def get_success_url(self):
return reverse('housewars:add_points')