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 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.forms.models import BaseInlineFormSet
|
||||
from django.utils import timezone
|
||||
|
||||
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):
|
||||
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.forms import (
|
||||
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 : "
|
||||
"ouverture le {:s}".format(opening))
|
||||
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:
|
||||
# Le tirage est fermé.
|
||||
participant, _ = (
|
||||
Participant.objects
|
||||
.get_or_create(user=request.user, tirage=tirage)
|
||||
)
|
||||
choices = participant.choixspectacle_set.order_by("priority")
|
||||
messages.error(request,
|
||||
" C'est fini : tirage au sort dans la journée !")
|
||||
return render(request, "bda/resume-inscription-tirage.html",
|
||||
{"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(
|
||||
Participant,
|
||||
ChoixSpectacle,
|
||||
fields=("spectacle", "double_choice", "priority"),
|
||||
formfield_callback=formfield_callback,
|
||||
)
|
||||
participant, _ = (
|
||||
Participant.objects
|
||||
.get_or_create(user=request.user, tirage=tirage)
|
||||
formset=InscriptionInlineFormSet,
|
||||
)
|
||||
|
||||
success = False
|
||||
stateerror = False
|
||||
if request.method == "POST":
|
||||
|
|
Loading…
Reference in a new issue