Merge branch 'Kerl/events' into 'master'

Kerl/events

- Utilise des formsets pour l'inscription aux événements dans la vue `registration`.
- Supprime du code mort : vue `gestioncof.views.registration_form2`.
- Ferme l'accès aux événements archivés via l'url `/event/<id>`.
- Demande la création d'un mot de passe  à l'inscription d'un membre n'ayant pas de compte clipper.

Fixes #58 

Fixes #22

Related to #52 


See merge request !72
This commit is contained in:
Martin Pepin 2016-08-21 11:58:01 +02:00
commit 7052eaf4b0
3 changed files with 140 additions and 134 deletions

View file

@ -8,6 +8,7 @@ from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
from django.forms.formsets import BaseFormSet, formset_factory
from django.db.models import Max from django.db.models import Max
from gestioncof.models import CofProfile, EventCommentValue, \ from gestioncof.models import CofProfile, EventCommentValue, \
@ -214,6 +215,32 @@ class RegistrationUserForm(forms.ModelForm):
fields = ("username", "first_name", "last_name", "email") fields = ("username", "first_name", "last_name", "email")
class RegistrationPassUserForm(RegistrationUserForm):
"""
Formulaire pour changer le mot de passe d'un utilisateur.
"""
password1 = forms.CharField(label=_('Mot de passe'),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_('Confirmation du mot de passe'),
widget=forms.PasswordInput)
def clean_password2(self):
pass1 = self.cleaned_data['password1']
pass2 = self.cleaned_data['password2']
if pass1 and pass2:
if pass1 != pass2:
raise forms.ValidationError(_('Mots de passe non identiques.'))
return pass2
def save(self, commit=True, *args, **kwargs):
user = super(RegistrationPassUserForm, self).save(commit, *args,
**kwargs)
user.set_password(self.cleaned_data['password2'])
if commit:
user.save()
return user
class RegistrationProfileForm(forms.ModelForm): class RegistrationProfileForm(forms.ModelForm):
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
super(RegistrationProfileForm, self).__init__(*args, **kw) super(RegistrationProfileForm, self).__init__(*args, **kw)
@ -263,17 +290,15 @@ STATUS_CHOICES = (('no', 'Non'),
class AdminEventForm(forms.Form): class AdminEventForm(forms.Form):
status = forms.ChoiceField(label="Inscription", status = forms.ChoiceField(label="Inscription", initial="no",
choices=STATUS_CHOICES, widget=RadioSelect) choices=STATUS_CHOICES, widget=RadioSelect)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
event = kwargs.pop("event") self.event = kwargs.pop("event")
self.event = event
registration = kwargs.pop("current_registration", None) registration = kwargs.pop("current_registration", None)
current_choices = \ current_choices, paid = \
registration.options.all() if registration is not None\ (registration.options.all(), registration.paid) \
else [] if registration is not None else ([], None)
paid = kwargs.pop("paid", None)
if paid is True: if paid is True:
kwargs["initial"] = {"status": "paid"} kwargs["initial"] = {"status": "paid"}
elif paid is False: elif paid is False:
@ -288,7 +313,7 @@ class AdminEventForm(forms.Form):
else: else:
choices[choice.event_option.id].append(choice.id) choices[choice.event_option.id].append(choice.id)
all_choices = choices all_choices = choices
for option in event.options.all(): for option in self.event.options.all():
choices = [(choice.id, choice.value) choices = [(choice.id, choice.value)
for choice in option.choices.all()] for choice in option.choices.all()]
if option.multi_choices: if option.multi_choices:
@ -310,7 +335,7 @@ class AdminEventForm(forms.Form):
initial=initial) initial=initial)
field.option_id = option.id field.option_id = option.id
self.fields["option_%d" % option.id] = field self.fields["option_%d" % option.id] = field
for commentfield in event.commentfields.all(): for commentfield in self.event.commentfields.all():
initial = commentfield.default initial = commentfield.default
if registration is not None: if registration is not None:
try: try:
@ -338,6 +363,22 @@ class AdminEventForm(forms.Form):
yield (self.fields[name].comment_id, value) yield (self.fields[name].comment_id, value)
class BaseEventRegistrationFormset(BaseFormSet):
def __init__(self, *args, **kwargs):
self.events = kwargs.pop('events')
self.current_registrations = kwargs.pop('current_registrations', None)
self.extra = len(self.events)
super(BaseEventRegistrationFormset, self).__init__(*args, **kwargs)
def _construct_form(self, index, **kwargs):
kwargs['event'] = self.events[index]
if self.current_registrations is not None:
kwargs['current_registration'] = self.current_registrations[index]
return super(BaseEventRegistrationFormset, self)._construct_form(
index, **kwargs)
EventFormset = formset_factory(AdminEventForm, BaseEventRegistrationFormset)
class CalendarForm(forms.ModelForm): class CalendarForm(forms.ModelForm):
subscribe_to_events = forms.BooleanField( subscribe_to_events = forms.BooleanField(
initial=True, initial=True,

View file

@ -12,16 +12,15 @@
<table> <table>
{{ user_form | bootstrap }} {{ user_form | bootstrap }}
{{ profile_form | bootstrap }} {{ profile_form | bootstrap }}
{% if event_forms %}
</table> </table>
{% for event_form in event_forms %} {{ event_formset.management_form }}
{% for event_form in event_formset %}
<hr /> <hr />
<h3>Inscription {{ event_form.event.title }} :</h2> <h3>Inscription {{ event_form.event.title }}&nbsp;:</h3>
<table> <table>
{{ event_form | bootstrap }} {{ event_form | bootstrap }}
</table> </table>
{% endfor %} {% endfor %}
{% endif %}
{% if login_clipper or member %} {% if login_clipper or member %}
<input type="hidden" name="user_exists" value="1" /> <input type="hidden" name="user_exists" value="1" />
{% endif %} {% endif %}

View file

@ -28,7 +28,8 @@ from gestioncof.models import CofProfile, Clipper
from gestioncof.decorators import buro_required, cof_required from gestioncof.decorators import buro_required, cof_required
from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \ from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \
SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \ SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \
RegistrationProfileForm, AdminEventForm, EventForm, CalendarForm RegistrationProfileForm, EventForm, CalendarForm, EventFormset, \
RegistrationPassUserForm
from bda.models import Tirage, Spectacle from bda.models import Tirage, Spectacle
@ -190,7 +191,7 @@ def update_event_form_comments(event, form, registration):
@login_required @login_required
def event(request, event_id): def event(request, event_id):
event = get_object_or_404(Event, id=event_id) event = get_object_or_404(Event, id=event_id)
if not event.registration_open: if (not event.registration_open) or event.old:
raise Http404 raise Http404
success = False success = False
if request.method == "POST": if request.method == "POST":
@ -315,45 +316,6 @@ def registration_set_ro_fields(user_form, profile_form):
profile_form.fields['login_clipper'].widget.attrs['readonly'] = True profile_form.fields['login_clipper'].widget.attrs['readonly'] = True
@buro_required
def registration_form(request, login_clipper=None, username=None):
member = None
if login_clipper:
clipper = get_object_or_404(Clipper, username=login_clipper)
try: # check if the given user is already registered
member = User.objects.filter(username=login_clipper).get()
username = member.username
login_clipper = None
except User.DoesNotExist:
# new user, but prefill
user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm()
user_form.fields['username'].initial = login_clipper
user_form.fields['email'].initial = \
login_clipper + "@clipper.ens.fr"
profile_form.fields['login_clipper'].initial = login_clipper
if clipper.fullname:
bits = clipper.fullname.split(" ")
user_form.fields['first_name'].initial = bits[0]
if len(bits) > 1:
user_form.fields['last_name'].initial = " ".join(bits[1:])
registration_set_ro_fields(user_form, profile_form)
if username:
member = get_object_or_404(User, username=username)
(profile, _) = CofProfile.objects.get_or_create(user=member)
# already existing, prefill
user_form = RegistrationUserForm(instance=member)
profile_form = RegistrationProfileForm(instance=profile)
registration_set_ro_fields(user_form, profile_form)
elif not login_clipper:
# new user
user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm()
return render(request, "registration_form.html",
{"user_form": user_form, "profile_form": profile_form,
"member": member, "login_clipper": login_clipper})
@buro_required @buro_required
def registration_form2(request, login_clipper=None, username=None): def registration_form2(request, login_clipper=None, username=None):
events = Event.objects.filter(old=False).all() events = Event.objects.filter(old=False).all()
@ -361,24 +323,26 @@ def registration_form2(request, login_clipper=None, username=None):
if login_clipper: if login_clipper:
clipper = get_object_or_404(Clipper, username=login_clipper) clipper = get_object_or_404(Clipper, username=login_clipper)
try: # check if the given user is already registered try: # check if the given user is already registered
member = User.objects.filter(username=login_clipper).get() member = User.objects.get(username=login_clipper)
username = member.username username = member.username
login_clipper = None login_clipper = None
except User.DoesNotExist: except User.DoesNotExist:
# new user, but prefill # new user, but prefill
user_form = RegistrationUserForm() # user
profile_form = RegistrationProfileForm() user_form = RegistrationUserForm(initial={
event_forms = [AdminEventForm(event=event) for event in events] 'username': login_clipper,
user_form.fields['username'].initial = login_clipper 'email': "%s@clipper.ens.fr" % login_clipper})
user_form.fields['email'].initial = \
login_clipper + "@clipper.ens.fr"
profile_form.fields['login_clipper'].initial = login_clipper
if clipper.fullname: if clipper.fullname:
bits = clipper.fullname.split(" ") bits = clipper.fullname.split(" ")
user_form.fields['first_name'].initial = bits[0] user_form.fields['first_name'].initial = bits[0]
if len(bits) > 1: if len(bits) > 1:
user_form.fields['last_name'].initial = " ".join(bits[1:]) user_form.fields['last_name'].initial = " ".join(bits[1:])
# profile
profile_form = RegistrationProfileForm(initial={
'login_clipper': login_clipper})
registration_set_ro_fields(user_form, profile_form) registration_set_ro_fields(user_form, profile_form)
# events
event_formset = EventFormset(events=events, prefix='events')
if username: if username:
member = get_object_or_404(User, username=username) member = get_object_or_404(User, username=username)
(profile, _) = CofProfile.objects.get_or_create(user=member) (profile, _) = CofProfile.objects.get_or_create(user=member)
@ -386,93 +350,94 @@ def registration_form2(request, login_clipper=None, username=None):
user_form = RegistrationUserForm(instance=member) user_form = RegistrationUserForm(instance=member)
profile_form = RegistrationProfileForm(instance=profile) profile_form = RegistrationProfileForm(instance=profile)
registration_set_ro_fields(user_form, profile_form) registration_set_ro_fields(user_form, profile_form)
event_forms = [] # events
current_registrations = []
for event in events: for event in events:
try: try:
current_registration = EventRegistration.objects.get( current_registrations.append(
user=member, event=event) EventRegistration.objects.get(user=member, event=event))
form = AdminEventForm(
event=event,
current_registration=current_registration,
paid=current_registration.paid)
except EventRegistration.DoesNotExist: except EventRegistration.DoesNotExist:
form = AdminEventForm(event=event) current_registrations.append(None)
event_forms.append(form) event_formset = EventFormset(
events=events, prefix='events',
current_registrations=current_registrations)
elif not login_clipper: elif not login_clipper:
# new user # new user
user_form = RegistrationUserForm() user_form = RegistrationPassUserForm()
profile_form = RegistrationProfileForm() profile_form = RegistrationProfileForm()
event_forms = [AdminEventForm(event=event) for event in events] event_formset = EventFormset(events=events, prefix='events')
return render(request, "registration_form.html", return render(request, "registration_form.html",
{"user_form": user_form, "profile_form": profile_form, {"user_form": user_form, "profile_form": profile_form,
"member": member, "login_clipper": login_clipper, "member": member, "login_clipper": login_clipper,
"event_forms": event_forms}) "event_formset": event_formset})
@buro_required @buro_required
def registration(request): def registration(request):
if request.POST: if request.POST:
request_dict = request.POST.copy() request_dict = request.POST.copy()
# num ne peut pas être défini manuellement
if "num" in request_dict: if "num" in request_dict:
del request_dict["num"] del request_dict["num"]
success = False
user_form = RegistrationUserForm(request_dict)
profile_form = RegistrationProfileForm(request_dict)
events = Event.objects.filter(old=False).all()
event_forms = \
[AdminEventForm(request_dict, event=event) for event in events]
user_form.is_valid()
profile_form.is_valid()
for event_form in event_forms:
event_form.is_valid()
member = None member = None
login_clipper = None login_clipper = None
success = False
# -----
# Remplissage des formulaires
# -----
if 'password1' in request_dict or 'password2' in request_dict:
user_form = RegistrationPassUserForm(request_dict)
else:
user_form = RegistrationUserForm
profile_form = RegistrationProfileForm(request_dict)
events = Event.objects.filter(old=False).all()
event_formset = EventFormset(events=events, data=request_dict,
prefix='events')
if "user_exists" in request_dict and request_dict["user_exists"]: if "user_exists" in request_dict and request_dict["user_exists"]:
username = request_dict["username"] username = request_dict["username"]
try: try:
member = User.objects.filter(username=username).get() member = User.objects.get(username=username)
(profile, _) = CofProfile.objects.get_or_create(user=member)
user_form = RegistrationUserForm(request_dict, instance=member) user_form = RegistrationUserForm(request_dict, instance=member)
profile_form = RegistrationProfileForm(request_dict,
instance=profile)
except User.DoesNotExist: except User.DoesNotExist:
try: try:
clipper = Clipper.objects.filter(username=username).get() clipper = Clipper.objects.get(username=username)
login_clipper = clipper.username login_clipper = clipper.username
except Clipper.DoesNotExist: except Clipper.DoesNotExist:
pass pass
for form in event_forms:
if not form.is_valid(): # -----
break # Validation des formulaires
if form.cleaned_data['status'] == 'no': # -----
continue
all_choices = get_event_form_choices(form.event, form) if user_form.is_valid():
if user_form.is_valid() and profile_form.is_valid() \
and not any([not form.is_valid() for form in event_forms]):
member = user_form.save() member = user_form.save()
(profile, _) = CofProfile.objects.get_or_create(user=member) profile, _ = CofProfile.objects.get_or_create(user=member)
was_cof = profile.is_cof was_cof = profile.is_cof
request_dict["num"] = profile.num request_dict["num"] = profile.num
# Maintenant on remplit le formulaire de profil
profile_form = RegistrationProfileForm(request_dict, profile_form = RegistrationProfileForm(request_dict,
instance=profile) instance=profile)
profile_form.is_valid() if profile_form.is_valid() and event_formset.is_valid():
profile_form.save() profile = profile_form.save()
(profile, _) = CofProfile.objects.get_or_create(user=member)
if profile.is_cof and not was_cof: if profile.is_cof and not was_cof:
send_custom_mail(member, "bienvenue") send_custom_mail(member, "bienvenue")
for form in event_forms: for form in event_formset:
if 'status' not in form.cleaned_data:
form.cleaned_data['status'] = 'no'
if form.cleaned_data['status'] == 'no': if form.cleaned_data['status'] == 'no':
try: try:
current_registration = EventRegistration.objects.get( current_registration = EventRegistration.objects \
user=member, event=form.event) .get(user=member, event=form.event)
current_registration.delete() current_registration.delete()
except EventRegistration.DoesNotExist: except EventRegistration.DoesNotExist:
pass pass
continue continue
all_choices = get_event_form_choices(form.event, form) all_choices = get_event_form_choices(form.event, form)
(current_registration, created_reg) = \ (current_registration, created_reg) = \
EventRegistration.objects.get_or_create(user=member, EventRegistration.objects.get_or_create(
event=form.event) user=member, event=form.event)
update_event_form_comments(form.event, form, update_event_form_comments(form.event, form,
current_registration) current_registration)
current_registration.options = all_choices current_registration.options = all_choices
@ -480,15 +445,16 @@ def registration(request):
(form.cleaned_data['status'] == 'paid') (form.cleaned_data['status'] == 'paid')
current_registration.save() current_registration.save()
if form.event.title == "Mega 15" and created_reg: if form.event.title == "Mega 15" and created_reg:
field = EventCommentField.objects.get(event=form.event, field = EventCommentField.objects.get(
name="Commentaires") event=form.event, name="Commentaires")
try: try:
comments = EventCommentValue.objects.get( comments = EventCommentValue.objects.get(
commentfield=field, commentfield=field,
registration=current_registration).content registration=current_registration).content
except EventCommentValue.DoesNotExist: except EventCommentValue.DoesNotExist:
comments = field.default comments = field.default
send_custom_mail(member, "mega", {"remarques": comments}) send_custom_mail(member, "mega",
{"remarques": comments})
success = True success = True
return render(request, "registration_post.html", return render(request, "registration_post.html",
{"success": success, {"success": success,
@ -496,7 +462,7 @@ def registration(request):
"profile_form": profile_form, "profile_form": profile_form,
"member": member, "member": member,
"login_clipper": login_clipper, "login_clipper": login_clipper,
"event_forms": event_forms}) "event_formset": event_formset})
else: else:
return render(request, "registration.html") return render(request, "registration.html")