Пользовательский валидатор WTForms - обязательно, если на RadioField - PullRequest
0 голосов
/ 12 июня 2018

Я позаимствовал валидатор, который требует от пользователя ввода данных, если значение другого поля является определенным значением:

class RequiredIf(object):
    def __init__(self, *args, **kwargs):
            self.conditions = kwargs
    def __call__(self, form, field):
            for name, data in self.conditions.items():
                if name not in form._fields:
                    Optional(form, field)
                else:
                    condition_field = form._fields.get(name)
                if condition_field.data == data and not field.data:
                    DataRequired()(form, field)
                    Optional()(form, field)

Это действительно хорошо работает, когда поле, содержащее аргумент validator, является TextField, но, похоже, он не работает, когда поле равно RadioField.Как я могу адаптировать валидатор так, чтобы он также работал на RadioFields?

Как есть, независимо от того, применяется условие проверки или нет, not a valid choice всегда возвращается для RadioField.

Заранее спасибо.

Например:

class new_form(Form):
    code=BooleanField('Do you code?')
    code2=RadioField('If so, what languages do you use?',
        choices=[('python','python'),('C++','C++')],
        validators=[RequiredIf(code=1)])

Независимо от того, установлен флажок BooleanField code или нет, this is not a valid choice всегда возвращается для code2.Мне нужен валидатор, который требует ввода для любого типа поля (включая RadioField), в зависимости от значения другого поля (code=1 в данном случае).

1 Ответ

0 голосов
/ 15 июня 2018

Обновлено! .Вы можете создать любую пользовательскую обработку, используя __call__.Пример:

from multidict import CIMultiDict
from wtforms import Form, RadioField, BooleanField


class RequiredIf(object):

    def __init__(self, **kwargs):
        self.conditions = kwargs

    def __call__(self, form, field):
        # NOTE! you can create here any custom processing
        current_value = form.data.get(field.name)
        if current_value == 'None':
            for condition_field, reserved_value in self.conditions.items():
                dependent_value = form.data.get(condition_field)
                if condition_field not in form.data:
                    continue
                elif dependent_value == reserved_value:
                    # just an example of error
                    raise Exception(
                        'Invalid value of field "%s". Field is required when %s==%s' % (
                            field.name,
                            condition_field,
                            dependent_value
                        ))

class NewForm(Form):
    code = BooleanField('Do you code?')
    code2 = RadioField(
        'If so, what languages do you use?',
        choices=[('python', 'python'), ('C++', 'C++')],
        validators=[RequiredIf(code=True)])

form = NewForm(formdata=CIMultiDict(code=True, code2='python'), )
form.validate()  # valid data - without errors

# invalid data
form = NewForm(formdata=CIMultiDict(code=True), )
form.validate()  # invalid data - Exception: Invalid value of field "code2". Field is required when code==True

Еще один пример с 2 RadioField:

class NewForm(Form):
    list_one = RadioField('City/Country', choices=['city', 'country'])
    list_two = RadioField(
        'Cities',
        choices=[('minsk', 'Minsk'), ('tbilisi', 'Tbilisi')],
        validators=[RequiredIf(list_one='city')])


form = NewForm(formdata=CIMultiDict(list_one='city', list_two='minsk'), )
form.validate()  # without errors
form = NewForm(formdata=CIMultiDict(list_one='country'), )
form.validate()  # without errors
form = NewForm(formdata=CIMultiDict(list_one='city'), )
form.validate()  # invalid data - Exception: Invalid value of field "list_two". Field is required when list_one==city

Надеюсь, это поможет.

...