Django-fr

Forum

  • Accueil
  • » Django-fr
  • » Recuperer les données d'un formulaire créé directement dans un templat

#1 26-10-2014 19:23:11

mattekenpis
Membre
Inscription : 26-10-2014
Messages : 2

Recuperer les données d'un formulaire créé directement dans un templat

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

#2 27-10-2014 10:53:06

jssevestre
Membre
Lieu : Fleurie - France
Inscription : 28-11-2012
Messages : 3
Site Web

Re : Recuperer les données d'un formulaire créé directement dans un templat

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

#3 05-11-2014 20:42:35

mattekenpis
Membre
Inscription : 26-10-2014
Messages : 2

Re : Recuperer les données d'un formulaire créé directement dans un templat

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

#4 12-11-2014 09:21:20

jssevestre
Membre
Lieu : Fleurie - France
Inscription : 28-11-2012
Messages : 3
Site Web

Re : Recuperer les données d'un formulaire créé directement dans un templat

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

  • Accueil
  • » Django-fr
  • » Recuperer les données d'un formulaire créé directement dans un templat

Pied de page des forums