From cfd4955672f014323a754a38fde7a39119bd4dae Mon Sep 17 00:00:00 2001 From: Bartuccio Antoine Date: Mon, 29 Apr 2019 19:22:01 +0200 Subject: [PATCH] clubs: clean up imports and move forms to external file --- club/forms.py | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++ club/views.py | 206 +++-------------------------------------------- 2 files changed, 232 insertions(+), 193 deletions(-) create mode 100644 club/forms.py diff --git a/club/forms.py b/club/forms.py new file mode 100644 index 00000000..fdfa8256 --- /dev/null +++ b/club/forms.py @@ -0,0 +1,219 @@ +# -*- coding:utf-8 -* +# +# Copyright 2016,2017 +# - Skia +# - Sli +# +# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, +# http://ae.utbm.fr. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License a published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA. +# +# + +from django.conf import settings +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField + +from club.models import Mailing, MailingSubscription, Club, Membership + +from core.models import User +from core.views.forms import SelectDate, SelectDateTime +from counter.models import Counter + + +class ClubEditForm(forms.ModelForm): + class Meta: + model = Club + fields = ["address", "logo", "short_description"] + + def __init__(self, *args, **kwargs): + super(ClubEditForm, self).__init__(*args, **kwargs) + self.fields["short_description"].widget = forms.Textarea() + + +class MailingForm(forms.ModelForm): + class Meta: + model = Mailing + fields = ("email", "club", "moderator") + + def __init__(self, *args, **kwargs): + club_id = kwargs.pop("club_id", None) + user_id = kwargs.pop("user_id", -1) # Remember 0 is treated as None + super(MailingForm, self).__init__(*args, **kwargs) + if club_id: + self.fields["club"].queryset = Club.objects.filter(id=club_id) + self.fields["club"].initial = club_id + self.fields["club"].widget = forms.HiddenInput() + if user_id >= 0: + self.fields["moderator"].queryset = User.objects.filter(id=user_id) + self.fields["moderator"].initial = user_id + self.fields["moderator"].widget = forms.HiddenInput() + + +class MailingSubscriptionForm(forms.ModelForm): + class Meta: + model = MailingSubscription + fields = ("mailing", "user", "email") + + def __init__(self, *args, **kwargs): + kwargs.pop("user_id", None) # For standart interface + club_id = kwargs.pop("club_id", None) + super(MailingSubscriptionForm, self).__init__(*args, **kwargs) + self.fields["email"].required = False + if club_id: + self.fields["mailing"].queryset = Mailing.objects.filter( + club__id=club_id, is_moderated=True + ) + + user = AutoCompleteSelectField( + "users", label=_("User"), help_text=None, required=False + ) + + +class SellingsFormBase(forms.Form): + begin_date = forms.DateTimeField( + ["%Y-%m-%d %H:%M:%S"], + label=_("Begin date"), + required=False, + widget=SelectDateTime, + ) + end_date = forms.DateTimeField( + ["%Y-%m-%d %H:%M:%S"], + label=_("End date"), + required=False, + widget=SelectDateTime, + ) + counter = forms.ModelChoiceField( + Counter.objects.order_by("name").all(), label=_("Counter"), required=False + ) + + +class ClubMemberForm(forms.Form): + """ + Form handling the members of a club + """ + + error_css_class = "error" + required_css_class = "required" + + users = AutoCompleteSelectMultipleField( + "users", + label=_("Users to add"), + help_text=_("Search users to add (one or more)."), + required=False, + ) + + def __init__(self, *args, **kwargs): + self.club = kwargs.pop("club") + self.request_user = kwargs.pop("request_user") + self.club_members = kwargs.pop("club_members", None) + if not self.club_members: + self.club_members = ( + self.club.members.filter(end_date=None).order_by("-role").all() + ) + self.request_user_membership = self.club.get_membership_for(self.request_user) + super(ClubMemberForm, self).__init__(*args, **kwargs) + + # Using a ModelForm binds too much the form with the model and we don't want that + # We want the view to process the model creation since they are multiple users + # We also want the form to handle bulk deletion + self.fields.update( + forms.fields_for_model( + Membership, + fields=("role", "start_date", "description"), + widgets={"start_date": SelectDate}, + ) + ) + + # Role is required only if users is specified + self.fields["role"].required = False + + # Start date and description are never really required + self.fields["start_date"].required = False + self.fields["description"].required = False + + self.fields["users_old"] = forms.ModelMultipleChoiceField( + User.objects.filter( + id__in=[ + ms.user.id + for ms in self.club_members + if ms.can_be_edited_by( + self.request_user, self.request_user_membership + ) + ] + ).all(), + label=_("Mark as old"), + required=False, + widget=forms.CheckboxSelectMultiple, + ) + if not self.request_user.is_root: + self.fields.pop("start_date") + + def clean_users(self): + """ + Check that the user is not trying to add an user already in the club + Also check that the user is valid and has a valid subscription + """ + cleaned_data = super(ClubMemberForm, self).clean() + users = [] + for user_id in cleaned_data["users"]: + user = User.objects.filter(id=user_id).first() + if not user: + raise forms.ValidationError( + _("One of the selected users doesn't exist"), code="invalid" + ) + if not user.is_subscribed: + raise forms.ValidationError( + _("User must be subscriber to take part to a club"), code="invalid" + ) + if self.club.get_membership_for(user): + raise forms.ValidationError( + _("You can not add the same user twice"), code="invalid" + ) + users.append(user) + return users + + def clean(self): + """ + Check user rights for adding an user + """ + cleaned_data = super(ClubMemberForm, self).clean() + + if "start_date" in cleaned_data and not cleaned_data["start_date"]: + # Drop start_date if allowed to edition but not specified + cleaned_data.pop("start_date") + + if not cleaned_data.get("users"): + # No user to add equals no check needed + return cleaned_data + + if cleaned_data.get("role", "") == "": + # Role is required if users exists + self.add_error("role", _("You should specify a role")) + return cleaned_data + + request_user = self.request_user + membership = self.request_user_membership + if not ( + cleaned_data["role"] <= settings.SITH_MAXIMUM_FREE_ROLE + or (membership is not None and membership.role >= cleaned_data["role"]) + or request_user.is_board_member + or request_user.is_root + ): + raise forms.ValidationError(_("You do not have the permission to do that")) + return cleaned_data diff --git a/club/views.py b/club/views.py index 7f50be06..c51b174f 100644 --- a/club/views.py +++ b/club/views.py @@ -23,6 +23,8 @@ # # + +from django.conf import settings from django import forms from django.views.generic import ListView, DetailView, TemplateView, View from django.views.generic.edit import DeleteView @@ -33,7 +35,6 @@ from django.core.urlresolvers import reverse, reverse_lazy from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext as _t -from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField from django.core.exceptions import PermissionDenied from django.shortcuts import get_object_or_404, redirect @@ -46,71 +47,24 @@ from core.views import ( PageEditViewBase, DetailFormView, ) -from core.views.forms import SelectDate, SelectDateTime -from club.models import Club, Membership, Mailing, MailingSubscription -from sith.settings import SITH_MAXIMUM_FREE_ROLE -from counter.models import Selling, Counter -from core.models import User, PageRev +from core.models import PageRev + +from counter.models import Selling + from com.views import ( PosterListBaseView, PosterCreateBaseView, PosterEditBaseView, PosterDeleteBaseView, ) -from com.models import Poster -from django.conf import settings - -# Custom forms - - -class ClubEditForm(forms.ModelForm): - class Meta: - model = Club - fields = ["address", "logo", "short_description"] - - def __init__(self, *args, **kwargs): - super(ClubEditForm, self).__init__(*args, **kwargs) - self.fields["short_description"].widget = forms.Textarea() - - -class MailingForm(forms.ModelForm): - class Meta: - model = Mailing - fields = ("email", "club", "moderator") - - def __init__(self, *args, **kwargs): - club_id = kwargs.pop("club_id", None) - user_id = kwargs.pop("user_id", -1) # Remember 0 is treated as None - super(MailingForm, self).__init__(*args, **kwargs) - if club_id: - self.fields["club"].queryset = Club.objects.filter(id=club_id) - self.fields["club"].initial = club_id - self.fields["club"].widget = forms.HiddenInput() - if user_id >= 0: - self.fields["moderator"].queryset = User.objects.filter(id=user_id) - self.fields["moderator"].initial = user_id - self.fields["moderator"].widget = forms.HiddenInput() - - -class MailingSubscriptionForm(forms.ModelForm): - class Meta: - model = MailingSubscription - fields = ("mailing", "user", "email") - - def __init__(self, *args, **kwargs): - kwargs.pop("user_id", None) # For standart interface - club_id = kwargs.pop("club_id", None) - super(MailingSubscriptionForm, self).__init__(*args, **kwargs) - self.fields["email"].required = False - if club_id: - self.fields["mailing"].queryset = Mailing.objects.filter( - club__id=club_id, is_moderated=True - ) - - user = AutoCompleteSelectField( - "users", label=_("User"), help_text=None, required=False - ) +from club.models import Club, Membership, Mailing, MailingSubscription +from club.forms import ( + MailingForm, + MailingSubscriptionForm, + ClubEditForm, + ClubMemberForm, +) class ClubTabsMixin(TabedViewMixin): @@ -306,122 +260,6 @@ class ClubToolsView(ClubTabsMixin, CanEditMixin, DetailView): current_tab = "tools" -class ClubMemberForm(forms.Form): - """ - Form handling the members of a club - """ - - error_css_class = "error" - required_css_class = "required" - - users = AutoCompleteSelectMultipleField( - "users", - label=_("Users to add"), - help_text=_("Search users to add (one or more)."), - required=False, - ) - - def __init__(self, *args, **kwargs): - self.club = kwargs.pop("club") - self.request_user = kwargs.pop("request_user") - self.club_members = kwargs.pop("club_members", None) - if not self.club_members: - self.club_members = ( - self.club.members.filter(end_date=None).order_by("-role").all() - ) - self.request_user_membership = self.club.get_membership_for(self.request_user) - super(ClubMemberForm, self).__init__(*args, **kwargs) - - # Using a ModelForm binds too much the form with the model and we don't want that - # We want the view to process the model creation since they are multiple users - # We also want the form to handle bulk deletion - self.fields.update( - forms.fields_for_model( - Membership, - fields=("role", "start_date", "description"), - widgets={"start_date": SelectDate}, - ) - ) - - # Role is required only if users is specified - self.fields["role"].required = False - - # Start date and description are never really required - self.fields["start_date"].required = False - self.fields["description"].required = False - - self.fields["users_old"] = forms.ModelMultipleChoiceField( - User.objects.filter( - id__in=[ - ms.user.id - for ms in self.club_members - if ms.can_be_edited_by( - self.request_user, self.request_user_membership - ) - ] - ).all(), - label=_("Mark as old"), - required=False, - widget=forms.CheckboxSelectMultiple, - ) - if not self.request_user.is_root: - self.fields.pop("start_date") - - def clean_users(self): - """ - Check that the user is not trying to add an user already in the club - Also check that the user is valid and has a valid subscription - """ - cleaned_data = super(ClubMemberForm, self).clean() - users = [] - for user_id in cleaned_data["users"]: - user = User.objects.filter(id=user_id).first() - if not user: - raise forms.ValidationError( - _("One of the selected users doesn't exist"), code="invalid" - ) - if not user.is_subscribed: - raise forms.ValidationError( - _("User must be subscriber to take part to a club"), code="invalid" - ) - if self.club.get_membership_for(user): - raise forms.ValidationError( - _("You can not add the same user twice"), code="invalid" - ) - users.append(user) - return users - - def clean(self): - """ - Check user rights for adding an user - """ - cleaned_data = super(ClubMemberForm, self).clean() - - if "start_date" in cleaned_data and not cleaned_data["start_date"]: - # Drop start_date if allowed to edition but not specified - cleaned_data.pop("start_date") - - if not cleaned_data.get("users"): - # No user to add equals no check needed - return cleaned_data - - if cleaned_data.get("role", "") == "": - # Role is required if users exists - self.add_error("role", _("You should specify a role")) - return cleaned_data - - request_user = self.request_user - membership = self.request_user_membership - if not ( - cleaned_data["role"] <= SITH_MAXIMUM_FREE_ROLE - or (membership is not None and membership.role >= cleaned_data["role"]) - or request_user.is_board_member - or request_user.is_root - ): - raise forms.ValidationError(_("You do not have the permission to do that")) - return cleaned_data - - class ClubMembersView(ClubTabsMixin, CanViewMixin, DetailFormView): """ View of a club's members @@ -485,24 +323,6 @@ class ClubOldMembersView(ClubTabsMixin, CanViewMixin, DetailView): current_tab = "elderlies" -class SellingsFormBase(forms.Form): - begin_date = forms.DateTimeField( - ["%Y-%m-%d %H:%M:%S"], - label=_("Begin date"), - required=False, - widget=SelectDateTime, - ) - end_date = forms.DateTimeField( - ["%Y-%m-%d %H:%M:%S"], - label=_("End date"), - required=False, - widget=SelectDateTime, - ) - counter = forms.ModelChoiceField( - Counter.objects.order_by("name").all(), label=_("Counter"), required=False - ) - - class ClubSellingView(ClubTabsMixin, CanEditMixin, DetailView): """ Sellings of a club