improve bda inscription form/view code
This commit is contained in:
parent
2eee8f58aa
commit
0d8a613f28
2 changed files with 41 additions and 45 deletions
36
bda/forms.py
36
bda/forms.py
|
@ -1,14 +1,42 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
from __future__ import print_function
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.forms.models import BaseInlineFormSet
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from bda.models import Attribution, Spectacle
|
from bda.models import Attribution, Spectacle
|
||||||
|
|
||||||
|
|
||||||
|
class InscriptionInlineFormSet(BaseInlineFormSet):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# self.instance is a Participant object
|
||||||
|
tirage = self.instance.tirage
|
||||||
|
|
||||||
|
# set once for all "spectacle" field choices
|
||||||
|
# - restrict choices to the spectacles of this tirage
|
||||||
|
# - force_choices avoid many db requests
|
||||||
|
spectacles = tirage.spectacle_set.select_related('location')
|
||||||
|
choices = [(sp.pk, str(sp)) for sp in spectacles]
|
||||||
|
self.force_choices('spectacle', choices)
|
||||||
|
|
||||||
|
def force_choices(self, name, choices):
|
||||||
|
"""Set choices of a field.
|
||||||
|
|
||||||
|
As ModelChoiceIterator (default use to get choices of a
|
||||||
|
ModelChoiceField), it appends an empty selection if requested.
|
||||||
|
|
||||||
|
"""
|
||||||
|
for form in self.forms:
|
||||||
|
field = form.fields[name]
|
||||||
|
if field.empty_label is not None:
|
||||||
|
field.choices = [('', field.empty_label)] + choices
|
||||||
|
else:
|
||||||
|
field.choices = choices
|
||||||
|
|
||||||
|
|
||||||
class TokenForm(forms.Form):
|
class TokenForm(forms.Form):
|
||||||
token = forms.CharField(widget=forms.widgets.Textarea())
|
token = forms.CharField(widget=forms.widgets.Textarea())
|
||||||
|
|
||||||
|
|
50
bda/views.py
50
bda/views.py
|
@ -32,6 +32,7 @@ from bda.models import (
|
||||||
from bda.algorithm import Algorithm
|
from bda.algorithm import Algorithm
|
||||||
from bda.forms import (
|
from bda.forms import (
|
||||||
TokenForm, ResellForm, AnnulForm, InscriptionReventeForm, SoldForm,
|
TokenForm, ResellForm, AnnulForm, InscriptionReventeForm, SoldForm,
|
||||||
|
InscriptionInlineFormSet,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,60 +158,27 @@ def inscription(request, tirage_id):
|
||||||
messages.error(request, "Le tirage n'est pas encore ouvert : "
|
messages.error(request, "Le tirage n'est pas encore ouvert : "
|
||||||
"ouverture le {:s}".format(opening))
|
"ouverture le {:s}".format(opening))
|
||||||
return render(request, 'bda/resume-inscription-tirage.html', {})
|
return render(request, 'bda/resume-inscription-tirage.html', {})
|
||||||
|
|
||||||
|
participant, _ = (
|
||||||
|
Participant.objects.select_related('tirage')
|
||||||
|
.get_or_create(user=request.user, tirage=tirage)
|
||||||
|
)
|
||||||
|
|
||||||
if timezone.now() > tirage.fermeture:
|
if timezone.now() > tirage.fermeture:
|
||||||
# Le tirage est fermé.
|
# Le tirage est fermé.
|
||||||
participant, _ = (
|
|
||||||
Participant.objects
|
|
||||||
.get_or_create(user=request.user, tirage=tirage)
|
|
||||||
)
|
|
||||||
choices = participant.choixspectacle_set.order_by("priority")
|
choices = participant.choixspectacle_set.order_by("priority")
|
||||||
messages.error(request,
|
messages.error(request,
|
||||||
" C'est fini : tirage au sort dans la journée !")
|
" C'est fini : tirage au sort dans la journée !")
|
||||||
return render(request, "bda/resume-inscription-tirage.html",
|
return render(request, "bda/resume-inscription-tirage.html",
|
||||||
{"choices": choices})
|
{"choices": choices})
|
||||||
|
|
||||||
def force_for(f, to_choices=None, **kwargs):
|
|
||||||
"""Overrides choices for ModelChoiceField.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
f (models.Field): To render as forms.Field
|
|
||||||
to_choices (dict): If a key `f.name` exists, f._choices is set to
|
|
||||||
its value.
|
|
||||||
|
|
||||||
"""
|
|
||||||
formfield = f.formfield(**kwargs)
|
|
||||||
if to_choices:
|
|
||||||
if f.name in to_choices:
|
|
||||||
choices = [('', '---------')] + to_choices[f.name]
|
|
||||||
formfield._choices = choices
|
|
||||||
return formfield
|
|
||||||
|
|
||||||
# Restrict spectacles choices to spectacles for this tirage.
|
|
||||||
spectacles = (
|
|
||||||
tirage.spectacle_set
|
|
||||||
.select_related('location')
|
|
||||||
)
|
|
||||||
spectacles_field_choices = [(sp.pk, str(sp)) for sp in spectacles]
|
|
||||||
|
|
||||||
# Allow for spectacle choices to be set once for all.
|
|
||||||
# Form display use 1 request instead of (#forms of formset * #spectacles).
|
|
||||||
# FIXME: Validation still generates too much requests...
|
|
||||||
formfield_callback = partial(
|
|
||||||
force_for,
|
|
||||||
to_choices={
|
|
||||||
'spectacle': spectacles_field_choices,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
BdaFormSet = inlineformset_factory(
|
BdaFormSet = inlineformset_factory(
|
||||||
Participant,
|
Participant,
|
||||||
ChoixSpectacle,
|
ChoixSpectacle,
|
||||||
fields=("spectacle", "double_choice", "priority"),
|
fields=("spectacle", "double_choice", "priority"),
|
||||||
formfield_callback=formfield_callback,
|
formset=InscriptionInlineFormSet,
|
||||||
)
|
|
||||||
participant, _ = (
|
|
||||||
Participant.objects
|
|
||||||
.get_or_create(user=request.user, tirage=tirage)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
success = False
|
success = False
|
||||||
stateerror = False
|
stateerror = False
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
|
Loading…
Reference in a new issue