From 0c9409fd4bc7346f46a127e780a32c3d83330a1f Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 18 Apr 2020 03:27:12 +0200 Subject: [PATCH] Improve WEI UI --- apps/permission/views.py | 27 ++++++++++++++++-- apps/wei/models.py | 11 ++++++++ apps/wei/urls.py | 3 +- apps/wei/views.py | 37 ++++++++++++++++++++++--- templates/base.html | 2 +- templates/wei/weiclub_info.html | 27 ++++++++++-------- templates/wei/weiclub_tables.html | 10 +++++++ templates/wei/weiregistration_form.html | 10 +++++-- 8 files changed, 105 insertions(+), 22 deletions(-) diff --git a/apps/permission/views.py b/apps/permission/views.py index bbd9872f..2e41810d 100644 --- a/apps/permission/views.py +++ b/apps/permission/views.py @@ -1,11 +1,34 @@ # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from permission.backends import PermissionBackend +from django.forms import HiddenInput +from django.views.generic import UpdateView + +from .backends import PermissionBackend class ProtectQuerysetMixin: + """ + Ensure that the user has the right to see or update objects. + Display 404 error if the user can't see an object, remove the fields the user can't + update on an update form (useful if the user can't change only specified fields). + """ def get_queryset(self, **kwargs): qs = super().get_queryset(**kwargs) - return qs.filter(PermissionBackend.filter_queryset(self.request.user, qs.model, "view")) + + def get_form(self, form_class=None): + form = super().get_form(form_class) + + if not isinstance(self, UpdateView): + return form + + # If we are in an UpdateView, we display only the fields the user has right to see. + # No worry if the user change the hidden fields: a 403 error will be performed if the user tries to make + # a custom request. + # We could also delete the field, but some views might be affected. + for key in form.base_fields: + if not PermissionBackend.check_perm(self.request.user, "wei.change_weiregistration_" + key, self.object): + form.fields[key].widget = HiddenInput() + + return form diff --git a/apps/wei/models.py b/apps/wei/models.py index b45f31c3..a4377acc 100644 --- a/apps/wei/models.py +++ b/apps/wei/models.py @@ -27,6 +27,10 @@ class WEIClub(Club): verbose_name=_("date end"), ) + @property + def is_current_wei(self): + return not WEIClub.objects.filter(date_start__gt=self.date_start).exists() + def update_membership_dates(self): """ We can't join the WEI next years. @@ -216,6 +220,13 @@ class WEIRegistration(models.Model): """ self.information_json = json.dumps(information) + @property + def is_validated(self): + try: + return self.membership is not None + except KeyError: + return False + def __str__(self): return str(self.user) diff --git a/apps/wei/urls.py b/apps/wei/urls.py index cf5b2c49..6f8ddbdc 100644 --- a/apps/wei/urls.py +++ b/apps/wei/urls.py @@ -3,13 +3,14 @@ from django.urls import path -from .views import WEIListView, WEICreateView, WEIDetailView, WEIUpdateView,\ +from .views import CurrentWEIDetailView, WEIListView, WEICreateView, WEIDetailView, WEIUpdateView,\ BusCreateView, BusManageView, BusUpdateView, BusTeamCreateView, BusTeamManageView, BusTeamUpdateView,\ WEIRegister1AView, WEIRegister2AView, WEIUpdateRegistrationView, WEIValidateRegistrationView app_name = 'wei' urlpatterns = [ + path('detail/', CurrentWEIDetailView.as_view(), name="current_wei_detail"), path('list/', WEIListView.as_view(), name="wei_list"), path('create/', WEICreateView.as_view(), name="wei_create"), path('detail//', WEIDetailView.as_view(), name="wei_detail"), diff --git a/apps/wei/views.py b/apps/wei/views.py index 02153f22..11db686a 100644 --- a/apps/wei/views.py +++ b/apps/wei/views.py @@ -6,8 +6,9 @@ from datetime import datetime, date from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.models import User from django.db.models import Q +from django.shortcuts import redirect from django.urls import reverse_lazy -from django.views.generic import DetailView, UpdateView, CreateView +from django.views.generic import DetailView, UpdateView, CreateView, View from django.utils.translation import gettext_lazy as _ from django_tables2 import SingleTableView from member.models import Membership, Club @@ -21,12 +22,19 @@ from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm, WEIMember from .tables import WEITable, WEIRegistrationTable, BusTable, BusTeamTable, WEIMembershipTable +class CurrentWEIDetailView(LoginRequiredMixin, View): + def get(self, *args, **kwargs): + wei = WEIClub.objects.order_by('date_start').last() + return redirect(reverse_lazy('wei:wei_detail', args=(wei.pk,))) + + class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): """ List existing WEI """ model = WEIClub table_class = WEITable + ordering = '-year' class WEICreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): @@ -85,6 +93,13 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('membership-page', 1)) context['pre_registrations'] = pre_registrations_table + my_registration = WEIRegistration.objects.filter(wei=club, user=self.request.user) + if my_registration.exists(): + my_registration = my_registration.get() + else: + my_registration = None + context["my_registration"] = my_registration + buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request.user, Bus, "view"))\ .filter(wei=self.object) bus_table = BusTable(data=buses, prefix="bus-") @@ -98,8 +113,14 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): date_end=datetime.now().date(), fee=0, ) - context["can_add_members"] = PermissionBackend() \ - .has_perm(self.request.user, "member.add_membership", empty_membership) + context["can_add_members"] = PermissionBackend \ + .check_perm(self.request.user, "member.add_membership", empty_membership) + + empty_bus = Bus( + wei=club, + name="", + ) + context["can_add_bus"] = PermissionBackend.check_perm(self.request.user, "wei.add_bus", empty_bus) return context @@ -261,6 +282,7 @@ class WEIRegister1AView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = _("Register 1A") + context['club'] = WEIClub.objects.get(pk=self.kwargs["wei_pk"]) return context def get_form(self, form_class=None): @@ -291,6 +313,7 @@ class WEIRegister2AView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = _("Register 2A+") + context['club'] = WEIClub.objects.get(pk=self.kwargs["wei_pk"]) return context def get_form(self, form_class=None): @@ -319,9 +342,15 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update model = WEIRegistration form_class = WEIRegistrationForm + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["club"] = self.object.wei + return context + def get_form(self, form_class=None): form = super().get_form(form_class) - del form.fields["user"] + if "user" in form.fields: + del form.fields["user"] return form def get_success_url(self): diff --git a/templates/base.html b/templates/base.html index 810927f9..f39f9bad 100644 --- a/templates/base.html +++ b/templates/base.html @@ -112,7 +112,7 @@ SPDX-License-Identifier: GPL-3.0-or-later {% endif %}