Сделать поле Обязательным условно Поле Flask Формы - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть две радиокнопки в форме flask. Если первый переключатель отмечен «Да», мне нужно, чтобы второй переключатель стал обязательным для заполнения пользователем. Я знаю, что есть способы сделать это в javascript, но я бы хотел сохранить все содержащиеся в flask wtform, поскольку именно это я и делал в основном, и я новичок в javascript.

Посмотрев на ранее заданные вопросы stackoverflow, я нашел следующее возможное решение, но это ничего не делает для меня. Когда я запускаю код с помощью следующего решения, оба переключателя являются обязательными. Я хочу, чтобы второе было обязательным, если первый отмечен только «Да».

class RequiredIf(InputRequired):
    field_flags = ('requiredif',)

    def __init__(self, other_field_name, message=None, *args, **kwargs):
        self.other_field_name = other_field_name
        self.message = message

    def __call__(self, form, field):
        other_field = form[self.other_field_name]
        if other_field is None:
            raise Exception('no field named "%s" in form' % self.other_field_name)
        if bool(other_field.data):
            super(RequiredIf, self).__call__(form, field)
        else:
            Optional().__call__(form, field)


class CheckInForm(FlaskForm):
    question1= RadioField('Question1 Label', choices=[('Yes', 'Yes'), ('No', 'No')], validators=[DataRequired()])

    question2 = RadioField('Question2 Label', choices=[('Yes', 'Yes'), ('No', 'No')], validators=[RequiredIf('question1')])
    submit = SubmitField('Submit Form', render_kw={"class": "btn btn-primary btn-block"})

Ниже приведен мой html файл:

{% extends "base.html" %}
{% import 'wtf.html' as wtf %}

<body>
{% block app_content %}
{% block content %}
    <h1><center>Check In</center></h1>
    <form action="" method="post" novalidate>
        {{ form.hidden_tag() }}


        <h5>&emsp;{{ form.question1.label }}</h5>
        {% for subfield in form.question1%}
            <tr>&emsp;
                <td>{{ subfield }}</td>
                <td>{{ subfield.label }}</td> &emsp;
            </tr>
        {% endfor %}
        {% for error in form.question1.errors %}
            <span style="color: red;">[{{ error }}]</span>
        {% endfor %}



        <h5>&emsp;{{ form.question2.label }}</h5>
        {% for subfield in form.question2%}
            <tr>&emsp;
                <td>{{ subfield }}</td>
                <td>{{ subfield.label }}</td> &emsp;
            </tr>
        {% endfor %}
        {% for error in form.question2.errors %}
            <span style="color: red;">[{{ error }}]</span>
        {% endfor %}

    </form>
{% endblock %}
{% endblock %}

1 Ответ

1 голос
/ 29 апреля 2020

Проблема с этой строкой:

if bool(other_field.data):

Когда выбор сделан для question1 other_field.data, это либо строковое значение «Да», либо «Нет», а bool(other_field.data) всегда True.

Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32
>>> print(bool('No'))
True
>>> print(bool('Yes'))
True

Вам необходимо явно проверить строковое значение 'No'. например,

class RequiredIf(InputRequired):
    field_flags = ('requiredif',)

    def __init__(self, other_field_name, message=None, *args, **kwargs):
        self.other_field_name = other_field_name
        self.message = message

    def __call__(self, form, field):
        other_field = form[self.other_field_name]
        if other_field is None:
            raise Exception('no field named "%s" in form' % self.other_field_name)
        if other_field.data == 'No':
            Optional().__call__(form, field)
        else:
            super(RequiredIf, self).__call__(form, field)
...