I'm building a web app using Flask to offer surveys to users. The number of questions on the survey and the type of questions isn't known until runtime. I finally have the code working properly, and would like some feedback on how pythonic the code is and what I can do to improve it.

To account for a single form page that can display multiple types of questions, I have the following in my forms.py file (I'm going with the PEP 8 notation that lines 99 characters long is acceptable for teams that prefer it):

class FieldsRequiredForm(FlaskForm):
    class Meta:
        def render_field(self, field, render_kw):
            render_kw.setdefault('required', True)
            return super().render_field(field, render_kw)

Here is the route code:

@bp.route('/survey/<string:slug>', methods=['GET', 'POST'])
def survey(slug):
    class SurveyForm(FieldsRequiredForm):

    survey = Survey.query.filter_by(slug=slug).first_or_404()
    questions = survey.questions
    question_ids = [question.id for question in questions]
    if 'answers' not in session:
        session['answers'] = json.dumps({id: None for id in question_ids})
        form = F()
    answers = json.loads(session['answers'])
    if request.method == 'POST':
        answers = json.loads(session['answers'])
    if None in answers.values():
        question = get_next_question()
        SurveyForm.question_id = HiddenField(default=question.id)
        if question.category == 'word':
            SurveyForm.answer = StringField(question.question)
        elif question.category == 'likert':
            SurveyForm.answer = RadioField(question.question, choices=tuple(likert().items()))
        SurveyForm.submit = SubmitField('Submit')
        SurveyForm.answer = StringField()
    form = F()
    if form.validate_on_submit():
        if None not in answers.values():
            if survey.ty:
                lines = iter(survey.ty.splitlines())
                with open('app/static/ty.txt', 'r') as f:
                    lines = f.readlines()
            ty = [line.strip() for line in lines]
            return render_template('ty.html', ty=ty)
        return redirect(url_for('survey.survey', slug=slug))
    return render_template('survey.html', form=form)

Please, tell me what I did wrong or could have done better.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.