feat: add ClubRole selection in election Role form

This commit is contained in:
imperosol
2026-05-31 12:38:14 +02:00
parent eb7f5def6e
commit 733bd49a42
3 changed files with 90 additions and 61 deletions
+24 -27
View File
@@ -1,6 +1,9 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from club.forms import ClubRoleChoiceField
from club.models import ClubRole
from club.widgets.ajax_select import AutoCompleteSelectMultipleClub
from core.models import User from core.models import User
from core.views.forms import SelectDateTime from core.views.forms import SelectDateTime
from core.views.widgets.ajax_select import ( from core.views.widgets.ajax_select import (
@@ -79,18 +82,20 @@ class VoteForm(forms.Form):
class RoleForm(forms.ModelForm): class RoleForm(forms.ModelForm):
"""Form for creating a role.""" """Form for creating a role."""
required_css_class = "required"
error_css_class = "error"
class Meta: class Meta:
model = Role model = Role
fields = ["title", "election", "description", "max_choice"] fields = ["club_role", "title", "description", "max_choice"]
widgets = {"election": AutoCompleteSelect} field_classes = {"club_role": ClubRoleChoiceField}
def __init__(self, *args, **kwargs): def __init__(self, *args, election: Election, **kwargs):
election_id = kwargs.pop("election_id", None)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if election_id: self.instance.election = election
self.fields["election"].queryset = Election.objects.filter( self.fields["club_role"].queryset = ClubRole.objects.filter(
id=election_id is_board=True, club__in=election.clubs.all()
).all() )
def clean(self): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()
@@ -108,21 +113,21 @@ class ElectionListForm(forms.ModelForm):
fields = ("title", "election") fields = ("title", "election")
widgets = {"election": AutoCompleteSelect} widgets = {"election": AutoCompleteSelect}
def __init__(self, *args, **kwargs): def __init__(self, *args, election: Election, **kwargs):
election_id = kwargs.pop("election_id", None)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if election_id: self.instance.election = election
self.fields["election"].queryset = Election.objects.filter(
id=election_id
).all()
class ElectionForm(forms.ModelForm): class ElectionForm(forms.ModelForm):
required_css_class = "required"
error_css_class = "error"
class Meta: class Meta:
model = Election model = Election
fields = [ fields = [
"title", "title",
"description", "description",
"clubs",
"archived", "archived",
"start_candidature", "start_candidature",
"end_candidature", "end_candidature",
@@ -134,21 +139,13 @@ class ElectionForm(forms.ModelForm):
"candidature_groups", "candidature_groups",
] ]
widgets = { widgets = {
"clubs": AutoCompleteSelectMultipleClub,
"edit_groups": AutoCompleteSelectMultipleGroup, "edit_groups": AutoCompleteSelectMultipleGroup,
"view_groups": AutoCompleteSelectMultipleGroup, "view_groups": AutoCompleteSelectMultipleGroup,
"vote_groups": AutoCompleteSelectMultipleGroup, "vote_groups": AutoCompleteSelectMultipleGroup,
"candidature_groups": AutoCompleteSelectMultipleGroup, "candidature_groups": AutoCompleteSelectMultipleGroup,
"start_date": SelectDateTime,
"end_date": SelectDateTime,
"start_candidature": SelectDateTime,
"end_candidature": SelectDateTime,
} }
start_date = forms.DateTimeField(
label=_("Start date"), widget=SelectDateTime, required=True
)
end_date = forms.DateTimeField(
label=_("End date"), widget=SelectDateTime, required=True
)
start_candidature = forms.DateTimeField(
label=_("Start candidature"), widget=SelectDateTime, required=True
)
end_candidature = forms.DateTimeField(
label=_("End candidature"), widget=SelectDateTime, required=True
)
@@ -0,0 +1,53 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans name=object_name %}Election role{% endtrans %}
{% endblock %}
{% block content %}
{% if object %}
<h1>{% trans election=election %}Create role for election "{{ election }}"{% endtrans %}</h1>
{% else %}
<h1>{% trans election=election %}Edit role for election "{{ election }}"{% endtrans %}</h1>
{% endif %}
<form action="" method="post" x-data="{role: null, title: '', description: ''}">
{% csrf_token %}
<div class="form-group">
{{ form.club_role.label_tag() }}
{{ form.club_role.errors }}
{{ form.club_role|add_attr("x-model.fill=role,autofocus=true") }}
<button
class="btn btn-blue"
@click.prevent="title = roles[role]?.title ?? '';
description = roles[role]?.description ?? '';"
>
{% trans %}autofill form{% endtrans %}
</button>
<span class="helptext">{{ form.club_role.help_text }}</span>
</div>
<div class="form-group">
{{ form.title.label_tag() }}
{{ form.title.errors }}
{{ form.title|add_attr("x-model.fill=title") }}
</div>
<div class="form-group">
{{ form.description.label_tag() }}
{{ form.description.errors }}
{{ form.description|add_attr("x-model.fill=description") }}
</div>
<div class="form-group">
{{ form.max_choice.as_field_group() }}
</div>
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form>
{% endblock %}
{% block script %}
<script>
const roles = {
{%- for role in form.club_role.field.queryset -%}
{{ role.id }}: { title: {{ role.name|tojson }}, description: {{ role.description|tojson }} },
{%- endfor -%}
};
</script>
{% endblock %}
+13 -34
View File
@@ -219,7 +219,7 @@ class ElectionCreateView(PermissionRequiredMixin, CreateView):
class RoleCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView): class RoleCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = Role model = Role
form_class = RoleForm form_class = RoleForm
template_name = "core/create.jinja" template_name = "election/role_form.jinja"
@cached_property @cached_property
def election(self): def election(self):
@@ -234,16 +234,14 @@ class RoleCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
id__in=self.request.user.all_groups id__in=self.request.user.all_groups
).exists() ).exists()
def get_initial(self):
return {"election": self.election}
def get_form_kwargs(self): def get_form_kwargs(self):
return super().get_form_kwargs() | {"election_id": self.election.id} return super().get_form_kwargs() | {"election": self.election}
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
return reverse( return reverse("election:detail", kwargs={"election_id": self.election.id})
"election:detail", kwargs={"election_id": self.object.election_id}
) def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {"election": self.election}
class ElectionListCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView): class ElectionListCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
@@ -267,16 +265,11 @@ class ElectionListCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView
) )
return not groups.isdisjoint(self.request.user.all_groups.keys()) return not groups.isdisjoint(self.request.user.all_groups.keys())
def get_initial(self):
return {"election": self.election}
def get_form_kwargs(self): def get_form_kwargs(self):
return super().get_form_kwargs() | {"election_id": self.election.id} return super().get_form_kwargs() | {"election": self.election}
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
return reverse( return reverse("election:detail", kwargs={"election_id": self.election.id})
"election:detail", kwargs={"election_id": self.object.election_id}
)
# Update view # Update view
@@ -288,18 +281,6 @@ class ElectionUpdateView(CanEditMixin, UpdateView):
template_name = "core/edit.jinja" template_name = "core/edit.jinja"
pk_url_kwarg = "election_id" pk_url_kwarg = "election_id"
def get_initial(self):
return {
"start_date": self.object.start_date.strftime("%Y-%m-%d %H:%M:%S"),
"end_date": self.object.end_date.strftime("%Y-%m-%d %H:%M:%S"),
"start_candidature": self.object.start_candidature.strftime(
"%Y-%m-%d %H:%M:%S"
),
"end_candidature": self.object.end_candidature.strftime(
"%Y-%m-%d %H:%M:%S"
),
}
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
return reverse_lazy("election:detail", kwargs={"election_id": self.object.id}) return reverse_lazy("election:detail", kwargs={"election_id": self.object.id})
@@ -327,7 +308,7 @@ class CandidatureUpdateView(LoginRequiredMixin, CanEditMixin, UpdateView):
class RoleUpdateView(CanEditMixin, UpdateView): class RoleUpdateView(CanEditMixin, UpdateView):
model = Role model = Role
form_class = RoleForm form_class = RoleForm
template_name = "core/edit.jinja" template_name = "election/role_form.jinja"
pk_url_kwarg = "role_id" pk_url_kwarg = "role_id"
def dispatch(self, request, *arg, **kwargs): def dispatch(self, request, *arg, **kwargs):
@@ -336,19 +317,14 @@ class RoleUpdateView(CanEditMixin, UpdateView):
raise PermissionDenied raise PermissionDenied
return super().dispatch(request, *arg, **kwargs) return super().dispatch(request, *arg, **kwargs)
def remove_fields(self):
self.form.fields.pop("election", None)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
self.form = self.get_form() self.form = self.get_form()
self.remove_fields()
return self.render_to_response(self.get_context_data(form=self.form)) return self.render_to_response(self.get_context_data(form=self.form))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
self.form = self.get_form() self.form = self.get_form()
self.remove_fields()
if ( if (
request.user.is_authenticated request.user.is_authenticated
and request.user.can_edit(self.object) and request.user.can_edit(self.object)
@@ -359,7 +335,7 @@ class RoleUpdateView(CanEditMixin, UpdateView):
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs["election_id"] = self.object.election.id kwargs["election"] = self.object.election
return kwargs return kwargs
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
@@ -367,6 +343,9 @@ class RoleUpdateView(CanEditMixin, UpdateView):
"election:detail", kwargs={"election_id": self.object.election.id} "election:detail", kwargs={"election_id": self.object.election.id}
) )
def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {"election": self.object.election}
# Delete Views # Delete Views