如何在Django表单向导中使用Formset(并动态更改参数extra)

如何在Django表单向导中使用Formset(并动态更改参数extra),django,forms,dynamic,wizard,formset,Django,Forms,Dynamic,Wizard,Formset,正如您在我的问题中所看到的,我试图在Django表单向导中使用表单集,并且我想根据上一步更改参数“extra” 我继续的方式显示了正确数量的表单,但似乎只有第一个表单被保存和验证。这是我的“相关”代码(抱歉,如果不是很清楚,我是Django的新手……: VIEWS.PY FORMS.PY #-*-编码:utf-8-*- 来自django导入表单 来自模型导入俱乐部、Frequence、Duree、模块 从crispy_forms.helper导入FormHelper 从crispy_forms.

正如您在我的问题中所看到的,我试图在Django表单向导中使用表单集,并且我想根据上一步更改参数“extra”

我继续的方式显示了正确数量的表单,但似乎只有第一个表单被保存和验证。这是我的“相关”代码(抱歉,如果不是很清楚,我是Django的新手……:

VIEWS.PY FORMS.PY
#-*-编码:utf-8-*-
来自django导入表单
来自模型导入俱乐部、Frequence、Duree、模块
从crispy_forms.helper导入FormHelper
从crispy_forms.layout导入布局,字段
#金斯克里特河畔地理信息
类别信息通用表格(forms.Form):
nom=forms.CharField(最大长度=100)
prenom=forms.CharField(最大长度=100)
club=forms.ModelChoiceField(queryset=club.objects.all())
电话联系人=forms.CharField(最大长度=100)
email\u contact=forms.EmailField()
annee=forms.ChoiceField(label=“Année détude”,choices=('1','1ère'),('2','2e'),('3','3e'),('4','4e'),('5','5e'),('6','6e'),错误消息={'required':“Entrez votre Ann e détude SVP'))
ecole=forms.CharField(最大长度=100)
从functools导入部分
DateInput=partial(forms.DateInput,{'class':'datepicker'})
从日期时间导入日期时间
焦耳=((0,'Lundi'),(1,'Mardi'),(2,'Mercredi'),(3,'Jeudi'),(4,'Vendredi'),)
类频率dureForm(forms.Form):
frequence=forms.ModelChoiceField(queryset=frequence.objects.all())
duree=forms.modelcooicefield(queryset=duree.objects.all())
jours=forms.multipleechoicefield(选项=jours,小部件=forms.CheckboxSelectMultiple)
date=forms.DateField(widget=DateInput(),必需=True)
def清洁(自清洁):
cleaned_data=super(frequencedureForm,self).clean()
首次登场日期=已清理的数据。获取(“首次登场日期”)
#Vérifie que les 2 champs sont validés
如果首次亮相日期:
如果首次登场日期=heure\U fin:
募捐表格。验证错误(“财务支持委员会”)
返回已清除的数据
#模块选择(时间和时间)
课程确认表(forms.Form):
标题='确认'
解决方案 我终于找到了解决办法。我的错误出现在模板中,因为我使用了一个crispy表单来呈现表单。我做了以下修改: 1°. 在我的表单定义中将self.helper.form_标记设置为False 2°. 将模板{{wizard.form.management_form}更改为{{wizard.form | crispy}}

就这样

from django.forms import BaseFormSet            
HoraireFormset = formset_factory(HoraireForm,formset=BaseFormSet, extra=2)            
formset = HoraireFormset

FORMS = [("infos_generales", InformationsGeneralesForm),
         ("frequence_duree", FrequenceDureeForm),
         ("horaire", formset),
         ("confirmation", ConfirmationForm)
         ]

TEMPLATES = {"infos_generales": "inscription/infos-generales.html",
             "frequence_duree": "inscription/frequence-duree.html",
             "horaire": "inscription/horaire.html",
             "confirmation": "inscription/confirmation.html"}

class InscriptionWizard(SessionWizardView):


def get_template_names(self):
    return [TEMPLATES[self.steps.current]]

def get_form(self, step=None, data=None, files=None):
    form = super(InscriptionWizard, self).get_form(step, data, files) 
    step = step or self.steps.current

    if step == 'horaire':
        current_form = self.get_cleaned_data_for_step('frequence_duree')
        days = current_form['jours']
        form.extra = len(days) # number of forms == number of days checked
        jours_de_la_semaine = ['Lundi', 'Mardi','Mercredi','Jeudi','Vendredi']
    return form 

def get_context_data(self, form, **kwargs):
    context = super(InscriptionWizard, self).get_context_data(form=form,      **kwargs)
    if self.steps.current == 'horaire':
        step_0_data = self.storage.get_step_data('infos_generales')            
        club = Club.objects.get(pk = step_0_data.get('infos_generales-club'))
        current_form = self.get_cleaned_data_for_step('frequence_duree')
        days = current_form['jours']
        modules = [Module.objects.filter(club=club, jour=day)[0] for day in days]
        context.update({'jours': modules})
    return context
# -*- coding: utf-8 -*-
from django import forms
from models import Club, Frequence, Duree, Module

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field

# informations générales sur l'inscrit
class InformationsGeneralesForm(forms.Form):
    nom = forms.CharField(max_length=100)
    prenom = forms.CharField(max_length=100)
    club = forms.ModelChoiceField(queryset= Club.objects.all())
    telephone_contact = forms.CharField(max_length=100)
    email_contact = forms.EmailField()
    annee = forms.ChoiceField(label="Année d'étude", choices=(('1','1ère'),('2','2e'),('3','3e'),('4','4e'),('5','5e'),('6','6e'),),error_messages={'required': "Entrez votre année d'étude SVP"})
    ecole = forms.CharField(max_length=100)

from functools import partial
DateInput = partial(forms.DateInput, {'class': 'datepicker'})
from datetime import datetime
jours = ((0,'Lundi'),(1,'Mardi'),(2,'Mercredi'),(3,'Jeudi'),(4,'Vendredi'),)  

class FrequenceDureeForm(forms.Form):
    frequence = forms.ModelChoiceField(queryset= Frequence.objects.all())
    duree =     forms.ModelChoiceField(queryset= Duree.objects.all())
    jours =     forms.MultipleChoiceField(choices= jours, widget=forms.CheckboxSelectMultiple)
    date_debut = forms.DateField(widget=DateInput(), required=True)

def clean(self):
    cleaned_data=super(FrequenceDureeForm, self).clean()
    date_debut=cleaned_data.get("date_debut")
     # Vérifie que les 2 champs sont validés
    if date_debut :
        if date_debut<datetime.now().date() :
            raise forms.ValidationError("Impossible de commencer les cours avant aujourd'hui...")
    return cleaned_data


# Horaire choisi (heure début et fin)
class HoraireForm(forms.Form):
    heure_debut = forms.TimeField(required=True, widget=forms.TimeInput(format='%H:%M', attrs={'class': 'timepicker','placeholder': "Introduisez l'heure à laquelle vous souhaitez commencer"}), input_formats=('%H:%M',))


 heure_fin   = forms.TimeField(required=True, widget=forms.TimeInput(format='%H:%M', attrs={'class': 'timepicker','placeholder': "Introduisez l'heure à laquelle vous souhaitez terminer"}),  input_formats=('%H:%M',))

def clean(self):
    cleaned_data=super(HoraireForm, self).clean()
    heure_debut = cleaned_data.get("heure_debut")
    heure_fin   = cleaned_data.get("heure_fin")
    # Vérifie que les 2 champs sont validés
    if heure_debut and heure_fin:
        if heure_debut>=heure_fin :
            raise forms.ValidationError("L'heure de fin du cours doit être supérieure à celle du début")
    return cleaned_data


# Sélection des modules (horaires et jours)
class ConfirmationForm(forms.Form):
    title = 'confirm'