Vous n'êtes pas identifié(e).
Salut,
J'ai un questionnaire que je génère directement dans un template (sans passer par un objet qui hérite de forms.Form)
Mon formulaire s'affiche bien, et je récupere bien les réponses dans ' request.POST ', la validation ' request.is_valid() ' fonctionne bien.
Mais lorsque je recupere form.cleaned_data, cette variable est vide....
Je pense que le probleme vient de:
form = forms.Form(request.POST or None, initial=initial)
Comme mon formulaire est constitué d'un groupe d'objets créés par une loop, je n'ai pas pu faire un formulaire qui hérite de forms.Form... Est-ce que cela pose un probleme?
Ma fonction View
# Page of the survey
def questionnaireForm(request):
initial={'surveyForm': request.session.get('surveyForm', None)}
form = forms.Form(request.POST or None, initial=initial) # Est-ce que ça ça marche?
if request.method == 'POST':
if form.is_valid():
print form.cleaned_data #Problème ici: cleaned_data est vide!
#request.session['surveyForm'] = form.cleaned_data
return HttpResponseRedirect(reverse('myapp:page2'))
all_questions_list = Question.objects.all()
context = {'all_questions': all_questions_list}
return render(request, 'myapp/questionnaireForm.html', context)
Model
class Question(models.Model):
question_text = models.CharField(max_length=200)
order_index = models.IntegerField()
answers = models.ManyToManyField(Answer) #Many-to-many relationship
def __unicode__(self):
return self.question_text
Et le template
<form method="post">
{% csrf_token %}
<ul>
{% for question in all_questions %}
<li>{{ question.question_text }}
<div>
{% for answer in question.answers.all %}
<input type="radio" name="question{{ question.id}}" id="answer{{ forloop.counter }}" value="{{ answer.id }}" />
<label for="answer{{ forloop.counter }}">{{ answer.answer_text }}</label><br />
{% endfor %}
</div>
</li>
{% endfor %}
</ul>
<input type="submit" value="Submit" />
</form>
Merci d'avance !
Hors ligne
Bonjour,
form.Form doit être hérité pour pouvoir te servir. Car en héritant, on défini quelle sont les données attendue, le format, ce qu'il faut en faire.
L'object 'form=form.Form(...)' que tu instancie ici est vide de sens, il n'a aucune idée de comment est constitué ton formulaire.
Il ne peut pas te servir. Tu dois faire tout le travail à la main !
La validation fonctionne car les données POST ne sont confrontées à rien: il n'y a rien à valider !
Pour créer ton formulaire, je pense que les formset et/ou model-formset peuvent t'être utiles.
Hors ligne
Salut s2j,
Merci pour ta réponse,
J'ai regardé le fonctionnement de FormSet et ModelFormSet.
En fait je ne vois pas trop comment je peux parvenir à mes fins sans trop compliquer le probleme
Quand je créé un Formset à partir de mon model Question:
QuestionFormSet = modelformset_factory(Question, fields=['question_text','order_index','answers'])
formset = QuestionFormSet(queryset=Question.objects.all())
et que je l'affiche, je me retrouve bien avec ma liste de questions et des comboboxes qui permettent de choisir les réponses (answers). Mais la liste de answers correspond à toutes celles définies dans la table Answer, et non celles que j'ai liée depuis le backoffice par la relation manytomany.
Est-ce que c'est compliqué de parvenir à obtenir une liste de choix pour chaque question, qui correspond aux elements "answer" liés par le manytomany?
Hors ligne
Salut,
Il faut effectivement prendre le contrôle sur la creation du champs answer, car le champ crée automatiquement suis la logique de la relation M2M. Pour ce faire, on fournit au modelformset_factory une base de formulaire 'à notre sauce' ( https://docs.djangoproject.com/en/dev/t … a-formset) :
from django.forms.models import BaseModelFormSet
class BaseQuestionFormset(BaseModelFormSet):
def add_fields(self, form, index):
super(BaseQuestionFormset, self).add_fields(form, index)
try:
instance = self.get_queryset()[index]
except IndexError:
instance = None
if instance:
form.fields["answers"] = forms.ChoiceField(
choices=((ans.pk, ans.text) for ans in instance.answers.all()),
widget=forms.widgets.RadioSelect)
Et on crée ensuite le formset
QuestionFormset = modelformset_factory(
Question,
fields=['text', 'index'], # NB on ne demande pas le champ 'answers' par défaut
formset=BaseQuestionFormset)
formset = QuestionFormset(queryset=Question.objects.all())
Hors ligne