from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http.response import HttpResponseRedirect, HttpResponseForbidden
from django.urls import reverse_lazy, reverse
from django.core.exceptions import PermissionDenied
from django.contrib import messages
from django.views import generic
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView, ModelFormMixin
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_POST
from .models import Person, Rank, EventLink, Division
from .forms import PersonForm, ManualEventLinkForm, PersonFilterForm, PersonCheckinForm, PersonPaidForm, TeamAssignForm
# Create your views here.
[docs]class IndexView(PermissionRequiredMixin, generic.ListView, generic.edit.FormMixin):
"""Main view for displaying the registered competetors.
Related to :class:`.IndexViewTable` and :class:`.IndexViewTableRow` which are used to redraw parts of this view
dynamically. Views :class:`PersonPaid` and :class:`PersonCheckin` are called by clicking buttons in this view.
"""
model = Person
form_class = PersonFilterForm
permission_required = 'accounts.view'
[docs] def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form = None
[docs] def get(self, request, *args, **kwargs):
self.form = self.get_form()
return super().get(request, *args, **kwargs)
[docs] def get_queryset(self):
qs = self.model.objects.all()
if self.form.is_valid():
qs = self.form.filter(qs)
return qs
[docs]class IndexViewTable(IndexView):
template_name = "registration/person_list_table.html"
[docs]class IndexViewTableRow(PermissionRequiredMixin, generic.DetailView):
model = Person
template_name = "registration/person_list_table_row.html"
permission_required = 'accounts.view'
[docs]class DetailView(PermissionRequiredMixin, generic.DetailView):
model = Person
permission_required = 'accounts.view'
[docs]class PersonCreate(PermissionRequiredMixin, CreateView):
model = Person
form_class = PersonForm
permission_required = 'accounts.edit'
[docs]class PersonUpdate(PermissionRequiredMixin, UpdateView):
model = Person
form_class = PersonForm
permission_required = 'accounts.edit'
[docs]class PersonDelete(PermissionRequiredMixin, DeleteView):
model = Person
success_url = reverse_lazy('registration:index')
permission_required = 'accounts.admin'
[docs]class PersonCheckin(PermissionRequiredMixin, UpdateView):
model = Person
form_class = PersonCheckinForm
permission_required = 'accounts.edit'
inline = False
[docs] def dispatch(self, request, *args, **kwargs):
if "inline" in request.GET:
self.inline = True
return super().dispatch(request, *args, **kwargs)
[docs] def get_success_url(self):
if self.inline:
return reverse('registration:index-table-row', args=[self.object.pk,])
else:
return reverse('registration:index')
[docs]class PersonPaid(PermissionRequiredMixin, UpdateView):
model = Person
form_class = PersonPaidForm
permission_required = 'accounts.edit'
inline = False
[docs] def dispatch(self, request, *args, **kwargs):
if "inline" in request.GET:
self.inline = True
return super().dispatch(request, *args, **kwargs)
[docs] def get_success_url(self):
if self.inline:
return reverse('registration:index-table-row', args=[self.object.pk,])
else:
return reverse('registration:index')
[docs]class DivisionList(generic.ListView):
model = Division
orderby = ('event', 'start_age', 'start_rank__order',)
[docs] def get_context_data(self, **kwargs):
context = super(DivisionList, self).get_context_data(**kwargs)
context['no_division_eventlist'] = EventLink.no_division_eventlinks()
return context
[docs]def add_division_info_context_data(view, context, **kwargs):
context['locked'] = view.object.get_format() is not None
context['confirmed_eventlinks'] = view.object.get_confirmed_eventlinks()
context['noshow_eventlinks'] = view.object.get_noshow_eventlinks()
if 'add_form' not in context:
context['add_form'] = ManualEventLinkForm()
if view.object.event.is_team and 'team_assign_form' not in context:
context['team_assign_form'] = TeamAssignForm(view.object)
return context
[docs]class DivisionInfo(PermissionRequiredMixin, generic.DetailView):
model = Division
permission_required = 'accounts.view'
[docs] def get_template_names(self):
if self.object.event.is_team:
return ['registration/division_team_detail.html']
else:
return ['registration/division_detail.html']
[docs] def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context = add_division_info_context_data(self, context)
return context
[docs]@method_decorator(require_POST, name='dispatch')
class DivisionAddManualPerson(PermissionRequiredMixin, generic.detail.SingleObjectMixin, generic.FormView):
form_class = ManualEventLinkForm
model = Division
permission_required = 'accounts.edit'
[docs] def get_template_names(self):
if self.object.event.is_team:
return ['registration/division_team_detail.html']
else:
return ['registration/division_detail.html']
[docs] def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['add_form'] = context['form']
del context['form']
context = add_division_info_context_data(self, context)
return context
[docs] def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super().post(request, *args, **kwargs)
[docs] def get_success_url(self):
return self.object.get_absolute_url()
[docs]@method_decorator(require_POST, name='dispatch')
class TeamAssignView(DivisionInfo, FormView):
form_class = TeamAssignForm
permission_required = 'accounts.edit'
[docs] def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['team_assign_form'] = context['form']
del context['form']
context = add_division_info_context_data(self, context)
return context
[docs] def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super().post(request, *args, **kwargs)
[docs] def get_success_url(self):
return self.object.get_absolute_url()
[docs]@method_decorator(require_POST, name='dispatch')
class DivisionDeleteManaualPerson(PermissionRequiredMixin, generic.DeleteView):
template_name = 'registration/division_detail.html' # Value doesn't matter since HTTP Get is forbidden
model = EventLink
permission_required = 'accounts.edit'
[docs] def get_object(self):
obj = super().get_object()
if obj.is_manual:
return obj
raise PermissionDenied
[docs] def get_success_url(self):
return self.object.division.get_absolute_url()
[docs] def delete(self, request, *args, **kwargs):
old_team = self.get_object().team
ret = super().delete(request, *args, **kwargs)
if old_team is not None and old_team.eventlink_set.count() == 0:
old_team.delete()
return ret
[docs]@method_decorator(require_POST, name='dispatch')
class DivisionBuild(PermissionRequiredMixin, generic.detail.SingleObjectMixin, generic.View):
model = Division
permission_required = 'accounts.edit'
[docs] def post(self, request, *args, **kwargs):
div = self.get_object()
fmt = div.get_format()
if fmt is None:
try:
fmt = div.build_format()
except Exception as e:
import logging
logging.getLogger().exception(e)
messages.error(request, 'Unable to create division. There may not be enough participants. Contact an administrator.')
return HttpResponseRedirect(div.get_absolute_url())
return HttpResponseRedirect(fmt.get_absolute_url())
[docs]class MessageDemoView(PermissionRequiredMixin, generic.TemplateView):
template_name = 'registration/message_demo.html'
permission_required = 'accounts.view'
[docs] def get(self, request, *args, **kwargs):
messages.debug(request, 'Debug message.')
messages.info(request, 'Info message.')
messages.success(request, 'Success message.')
messages.warning(request, 'Warning message.')
messages.error(request, 'Error message.')
return super().get(request, *args, **kwargs)