Utilisation d'un formset pour l'inscription

- Changements mineurs dans `AdminEventForm`
- Ajout d'une base pour le formset : `BaseEventRegistrationFormset`
- Adaptation des vues de l'inscription et suppression d'une vue inutile.
This commit is contained in:
Martin Pépin 2016-08-07 18:47:59 +02:00
parent 19456756e4
commit b60b9f4e17
3 changed files with 54 additions and 82 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
from django.db.models import Max from django.db.models import Max
from gestioncof.models import CofProfile, EventCommentValue, \ from gestioncof.models import CofProfile, EventCommentValue, \
@ -263,17 +264,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 +287,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 +309,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 +337,21 @@ 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)
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

@ -14,6 +14,7 @@ from django.http import Http404, HttpResponse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import login as django_login_view from django.contrib.auth.views import login as django_login_view
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.forms.models import formset_factory
import django.utils.six as six import django.utils.six as six
from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \ from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \
@ -27,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, AdminEventForm, EventForm, CalendarForm, \
BaseEventRegistrationFormset
from bda.models import Tirage, Spectacle from bda.models import Tirage, Spectacle
@ -313,49 +315,12 @@ 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()
member = None member = None
EventFormset = formset_factory(AdminEventForm,
BaseEventRegistrationFormset)
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
@ -366,10 +331,10 @@ def registration_form2(request, login_clipper=None, username=None):
# new user, but prefill # new user, but prefill
user_form = RegistrationUserForm() user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm() profile_form = RegistrationProfileForm()
event_forms = [AdminEventForm(event=event) for event in events] event_formset = EventFormset(events=events, prefix='events')
user_form.fields['username'].initial = login_clipper user_form.fields['username'].initial = login_clipper
user_form.fields['email'].initial = \ user_form.fields['email'].initial = "%s@clipper.ens.fr" \
login_clipper + "@clipper.ens.fr" % login_clipper
profile_form.fields['login_clipper'].initial = login_clipper profile_form.fields['login_clipper'].initial = login_clipper
if clipper.fullname: if clipper.fullname:
bits = clipper.fullname.split(" ") bits = clipper.fullname.split(" ")
@ -384,27 +349,25 @@ 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 = [] 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 = RegistrationUserForm()
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
@ -417,12 +380,13 @@ def registration(request):
user_form = RegistrationUserForm(request_dict) user_form = RegistrationUserForm(request_dict)
profile_form = RegistrationProfileForm(request_dict) profile_form = RegistrationProfileForm(request_dict)
events = Event.objects.filter(old=False).all() events = Event.objects.filter(old=False).all()
event_forms = \ EventFormset = formset_factory(AdminEventForm,
[AdminEventForm(request_dict, event=event) for event in events] BaseEventRegistrationFormset)
event_formset = EventFormset(events=events, data=request_dict,
prefix='events')
user_form.is_valid() user_form.is_valid()
profile_form.is_valid() profile_form.is_valid()
for event_form in event_forms: event_formset.is_valid()
event_form.is_valid()
member = None member = None
login_clipper = None login_clipper = None
if "user_exists" in request_dict and request_dict["user_exists"]: if "user_exists" in request_dict and request_dict["user_exists"]:
@ -439,26 +403,21 @@ def registration(request):
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
if form.cleaned_data['status'] == 'no':
continue
all_choices = get_event_form_choices(form.event, form)
if user_form.is_valid() and profile_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]): and event_formset.is_valid():
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
profile_form = RegistrationProfileForm(request_dict, profile_form = RegistrationProfileForm(request_dict,
instance=profile) instance=profile)
profile_form.is_valid()
profile_form.save() profile_form.save()
(profile, _) = CofProfile.objects.get_or_create(user=member) (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.get(
@ -494,7 +453,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")