147 lines
4.9 KiB
Python
147 lines
4.9 KiB
Python
from django.forms import formset_factory
|
|
from django.shortcuts import render, redirect, get_object_or_404
|
|
from django.urls import reverse_lazy
|
|
from django.views.generic.edit import CreateView
|
|
from django.views.generic import TemplateView
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.db import transaction
|
|
from functools import reduce
|
|
|
|
from .forms import CustomUserCreationForm, CustomUserChangeForm, StudentForm
|
|
from .models import Announcement, Edition, Student
|
|
|
|
|
|
class SignUpView(CreateView):
|
|
form_class = CustomUserCreationForm
|
|
success_url = reverse_lazy('login')
|
|
template_name = 'registration/signup.html'
|
|
|
|
|
|
@login_required
|
|
def UpdateAccountView(request):
|
|
if request.method == 'POST':
|
|
form = CustomUserChangeForm(request.POST, instance=request.user)
|
|
if form.is_valid():
|
|
form.save()
|
|
else:
|
|
form = CustomUserChangeForm(instance=request.user)
|
|
|
|
return render(request, 'user/account.html', {'account_page': 'is-active', 'account_tab': 'is-active', 'ongoing': Edition.current(), 'form': form})
|
|
|
|
|
|
@login_required
|
|
def SubmitStudentsView(request):
|
|
edition = Edition.current()
|
|
|
|
if edition is not None:
|
|
identifier = f'{edition.year}-{request.user.id}-'
|
|
queryset = Student.objects.filter(identifier__startswith=identifier)
|
|
|
|
if edition.submissions is not True:
|
|
identifier = f'{edition.year}-{request.user.id}'
|
|
queryset = Student.objects.filter(identifier__startswith=identifier).order_by('identifier')
|
|
return render(request, 'user/submission.html', {'account_page': 'is-active', 'submission_tab': 'is-active', 'ongoing': edition, 'students': queryset})
|
|
|
|
ArticleFormSet = formset_factory(StudentForm, extra=2, max_num=3, min_num=1)
|
|
|
|
if request.method == 'POST':
|
|
with transaction.atomic():
|
|
formset = ArticleFormSet(request.POST)
|
|
if formset.is_valid():
|
|
queryset.delete()
|
|
|
|
students = filter(lambda x: x != {}, formset.cleaned_data)
|
|
for index, data in enumerate(students):
|
|
Student.objects.update_or_create(identifier=f'{edition.year}-{request.user.id}-{index + 1}', defaults=data)
|
|
else:
|
|
formset = ArticleFormSet(initial=list(map(lambda x: x.__dict__, queryset)))
|
|
|
|
return render(request, 'user/submit.html', {'account_page': 'is-active', 'submission_tab': 'is-active', 'ongoing': True, 'formset': formset})
|
|
else:
|
|
return redirect(reverse_lazy('account'))
|
|
|
|
|
|
class HomeView(TemplateView):
|
|
template_name = 'home.html'
|
|
|
|
|
|
class NewsView(TemplateView):
|
|
template_name = 'news.html'
|
|
extra_context = {
|
|
'news_page': 'is-active',
|
|
'announcements': Announcement.objects.all(),
|
|
}
|
|
|
|
|
|
class RulesView(TemplateView):
|
|
template_name = 'rules.html'
|
|
extra_context = {
|
|
'rules_page': 'is-active'
|
|
}
|
|
|
|
|
|
class TestsView(TemplateView):
|
|
template_name = 'tests.html'
|
|
extra_context = {
|
|
'tests_page': 'is-active',
|
|
'editions': Edition.objects.order_by('-year')
|
|
}
|
|
|
|
|
|
def ScoresRedirect(request):
|
|
latest = Edition.objects.filter(scores_available=True).order_by('-year').first()
|
|
|
|
if latest is not None:
|
|
return redirect(reverse_lazy('scores', args=[latest.year]))
|
|
else:
|
|
return redirect(reverse_lazy('home'))
|
|
|
|
|
|
def ScoresView(request, year):
|
|
edition = get_object_or_404(Edition, year=year)
|
|
|
|
if edition.scores_available is not True:
|
|
return redirect('scores')
|
|
|
|
students = Student.objects.filter(identifier__startswith=year)
|
|
|
|
schools = map(lambda x: {
|
|
'id': x.identifier.split('-')[1],
|
|
'name': x.school_name,
|
|
'town': x.school_town
|
|
}, students)
|
|
schools = list({school['id']: school for school in schools}.values())
|
|
|
|
individual = map(lambda x: {
|
|
**x.__dict__,
|
|
'score': x.score_first * x.score_second,
|
|
'title': 'Laureat' if x.score_first * x.score_second >= edition.laureate_threshold else 'Wyróżnienie'
|
|
}, students.filter(score_first__gte=edition.entry_threshold))
|
|
individual = filter(lambda x: x['score'] >= edition.award_threshold, individual)
|
|
|
|
teams = []
|
|
for school in schools:
|
|
team = students.filter(identifier__startswith=f'{year}-' + school['id'] + '-')
|
|
|
|
score_first = reduce(lambda x, y: x + y.score_first, team, 0)
|
|
score_second = reduce(lambda x, y: x + y.score_second, team, 0)
|
|
|
|
teams.append({**school, 'score': score_first * score_second})
|
|
|
|
context = {
|
|
'scores_page': 'is-active',
|
|
'year': year,
|
|
'editions': Edition.objects.filter(scores_available=True),
|
|
'individual': sorted(individual, key=lambda x: -x['score']),
|
|
'teams': sorted(teams, key=lambda x: -x['score'])
|
|
}
|
|
|
|
return render(request, 'scores.html', context)
|
|
|
|
|
|
class ContactView(TemplateView):
|
|
template_name = 'contact.html'
|
|
extra_context = {
|
|
'contact_page': 'is-active'
|
|
}
|