2017-09-24 4 views
0

Je crée une application Web semblable à un quiz pour apprendre des langues en utilisant Flask, Jinja, WTForms, SqlAlchemy, etc. Une fois qu'un utilisateur termine un tel cours de langue en passant avec succès tous les niveaux stockés dans Fichier JSON Je veux que l'application lui offre un mode de pratique, où l'utilisateur répondra au hasard des niveaux sélectionnés.validate_on_submit() échoue lorsque les choix de RadioButton sont générés dynamiquement

Quand je lance l'application, je peux voir les boutons radio générés avec des valeurs de niveau aléatoire que je veux, mais quand je choisis une réponse et de le soumettre, form.validate_on_submit() renvoie Faux et retourne form.errors {'practiceform': [u'Pas un choix valide ']}. Lorsque je code en dur la valeur de la variable currentLevel, cela fonctionne correctement.

views.py

@user_blueprint.route('/courses/<course>/quiz/practice',methods=['GET','POST']) 
@login_required 
def practice(course): 
    courseClass = class_for_name("project.models", course.capitalize()) 
    courses = courseClass.query.filter_by(email=current_user.email).first() 
    maxLevel = courseClass.query.filter_by(email=current_user.email).first().get_maxLevel() 
    currentLevel = randint(0, maxLevel-1) # If this value is hard-coded or fetched from db, it works correctly 

    dic = generateQuestion(course, currentLevel) 
    display = dic["display"] 
    correct = dic["correct"] 
    options = dic["options"] 

    form = PracticeForm(request.form) 
    form.practiceform.choices = [(option, option) for option in options] 


    if form.validate_on_submit(): 
     practiceForm = form.practiceform.data 

     if ((practiceForm == correct) and courses): 
      # Do something 
      flash("Nice job", 'success') 
      return redirect(url_for('user.practice', course=course)) 

     else: 
      # Do something else 
      flash("Wrong answer", 'danger') 
      return redirect(url_for('user.practice', course=course)) 

    return render_template('courses/practice.html', form=form, display=display) 

forms.py

class PracticeForm(Form): 

    practiceform = RadioField('practice') 

practice.html

{% extends "_base.html" %} 
{% block content %} 

<form action='' method='POST' role='form'> 
    <p> 
     <!-- Tried put form.csrf, form.csrf_token, form.hidden_tag() here --> 
     {{ form.practiceform() }} 
    </p> 
    <input type="submit" value="submit" /> 
</form> 
{% endblock %} 

Alors, que suis-je missin g là? Qu'est-ce qui fait la différence entre le niveau 25 codé en dur, qui fonctionne correctement ou si le nombre 25 est généré aléatoirement dans randint?

Répondre

0

Je trouve que randint() a causé le problème parce que la méthode de la pratique (cours) a été appelée sur les actions GET et POST qui ont conduit à avoir deux entiers différents -> deux formes différentes la plupart du temps. J'ai donc refactorisé le code. gardé la méthode pratique (cours) pour l'action GET et créé une nouvelle méthode qui gère l'action POST et cela a résolu le problème.

0

Ma conjecture est que option est un int, bug WTForms obtenir un str de request.form.

Lorsque les données revient de demandes elle est traitée comme string par WTForms sauf si vous spécifiez un type explicitement avec le coerce kwarg du constructeur wtforms.fields.*Field:

practiceform = RadioField('practice', coerce=int)