Fügt ein neues Abstimmungs-Feature hinzu, das es Head Coaches ermöglicht,
Umfragen innerhalb ihres Teams zu erstellen und zu verwalten.
Teammitglieder können Umfragen ansehen und daran teilnehmen.
Wesentliche Änderungen:
- **Neue 'polls'-App:** Enthält Modelle, Formulare, Views und Templates.
- **Modelle und :** Definieren die Struktur für Umfragen
(Frage, Team, Ersteller, Mehrfachauswahl-Option) und die Auswahlmöglichkeiten
(Text, Stimmen).
- **Formulare und :** Für die Erstellung von Umfragen
und deren Auswahlmöglichkeiten.
- **Views:**
- : Zeigt alle für den Benutzer relevanten Umfragen an.
- : Ermöglicht Head Coaches das Erstellen neuer Umfragen
(inkl. Fehlerbehebung bei der Formularinitialisierung).
- : Zeigt Details einer Umfrage an und ermöglicht die
Stimmabgabe.
- : Zeigt die Ergebnisse einer Umfrage an.
- : Funktion für die Stimmabgabe.
- **Templates:** Spezifische Templates für alle Umfrage-Views.
- **URL-Konfiguration:** Neue URLs für die 'polls'-App und Einbindung in die
Haupt-URL-Konfiguration.
- **Navigationslink:** Ein neuer Link 'Polls' in der Hauptnavigation für
authentifizierte Benutzer.
- **Migrationen:** Datenbankmigrationen für die neuen - und -Modelle.
127 lines
4.6 KiB
Python
127 lines
4.6 KiB
Python
from django.shortcuts import render, get_object_or_404, redirect
|
|
from django.views.generic import ListView, CreateView, DetailView
|
|
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
|
from django.urls import reverse_lazy, reverse
|
|
from django.db import transaction
|
|
from .models import Poll, Choice
|
|
from .forms import PollForm, ChoiceFormSet
|
|
from clubs.models import Team
|
|
from accounts.models import CustomUser
|
|
|
|
class PollListView(LoginRequiredMixin, ListView):
|
|
model = Poll
|
|
template_name = 'polls/poll_list.html'
|
|
context_object_name = 'polls'
|
|
|
|
def get_queryset(self):
|
|
user = self.request.user
|
|
user_teams = set()
|
|
|
|
if user.team:
|
|
user_teams.add(user.team)
|
|
|
|
# Add teams where the user is a coach or assistant
|
|
user_teams.update(user.coached_teams.all())
|
|
user_teams.update(user.assisted_teams.all())
|
|
|
|
# Add teams of children for parents
|
|
if hasattr(user, 'children'):
|
|
for child in user.children.all():
|
|
if child.team:
|
|
user_teams.add(child.team)
|
|
|
|
return Poll.objects.filter(team__in=user_teams).order_by('-created_at')
|
|
|
|
class PollCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
|
|
model = Poll
|
|
form_class = PollForm
|
|
template_name = 'polls/poll_form.html'
|
|
|
|
def test_func(self):
|
|
# Only head coaches can create polls
|
|
return self.request.user.coached_teams.exists()
|
|
|
|
def get_context_data(self, **kwargs):
|
|
data = super().get_context_data(**kwargs)
|
|
if self.request.POST:
|
|
data['choice_formset'] = ChoiceFormSet(self.request.POST)
|
|
else:
|
|
data['choice_formset'] = ChoiceFormSet()
|
|
# Filter the team queryset for the form to only show teams the user coaches
|
|
data['form'].fields['team'].queryset = self.request.user.coached_teams.all()
|
|
return data
|
|
|
|
def form_valid(self, form):
|
|
context = self.get_context_data()
|
|
choice_formset = context['choice_formset']
|
|
|
|
# Set the creator before saving the poll
|
|
form.instance.creator = self.request.user
|
|
|
|
if choice_formset.is_valid():
|
|
self.object = form.save()
|
|
|
|
with transaction.atomic():
|
|
for choice_form in choice_formset:
|
|
if choice_form.cleaned_data.get('choice_text'):
|
|
Choice.objects.create(
|
|
poll=self.object,
|
|
choice_text=choice_form.cleaned_data['choice_text']
|
|
)
|
|
return redirect(self.get_success_url())
|
|
else:
|
|
return self.form_invalid(form)
|
|
|
|
def get_success_url(self):
|
|
return reverse('polls:poll_list')
|
|
|
|
class PollDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
|
|
model = Poll
|
|
template_name = 'polls/poll_detail.html'
|
|
|
|
def test_func(self):
|
|
# Check if user is part of the team for which the poll is
|
|
poll = self.get_object()
|
|
user = self.request.user
|
|
|
|
user_teams = set()
|
|
if user.team:
|
|
user_teams.add(user.team)
|
|
user_teams.update(user.coached_teams.all())
|
|
user_teams.update(user.assisted_teams.all())
|
|
if hasattr(user, 'children'):
|
|
for child in user.children.all():
|
|
if child.team:
|
|
user_teams.add(child.team)
|
|
|
|
return poll.team in user_teams
|
|
|
|
def vote(request, poll_id):
|
|
poll = get_object_or_404(Poll, pk=poll_id)
|
|
user = request.user
|
|
|
|
if request.method == 'POST':
|
|
if poll.multiple_choice:
|
|
selected_choice_ids = request.POST.getlist('choice')
|
|
# First, remove user's previous votes for this poll
|
|
poll.choices.filter(votes=user).update(votes=None)
|
|
# Then, add new votes
|
|
for choice_id in selected_choice_ids:
|
|
choice = get_object_or_404(Choice, pk=choice_id)
|
|
choice.votes.add(user)
|
|
else:
|
|
selected_choice_id = request.POST.get('choice')
|
|
if selected_choice_id:
|
|
# Remove user's vote from all choices in this poll first
|
|
for choice in poll.choices.all():
|
|
choice.votes.remove(user)
|
|
# Add the new vote
|
|
choice = get_object_or_404(Choice, pk=selected_choice_id)
|
|
choice.votes.add(user)
|
|
|
|
return redirect('polls:poll_results', pk=poll.id)
|
|
|
|
class PollResultsView(LoginRequiredMixin, DetailView):
|
|
model = Poll
|
|
template_name = 'polls/poll_results.html'
|
|
context_object_name = 'poll' |