Найти - Пользователи
Полная версия: Как правильно написать фильтр для flask_wtform
Начало » Python для новичков » Как правильно написать фильтр для flask_wtform
1
demonworm
Здравствуйте.

Подскажите, как правильно писать фильтры для wtform через flask. В оф. документации https://wtforms.readthedocs.io/en/3.1.x/fields/ описание куцое и даже пример, который там привели, не работает. Моя попытка внедрить свой фильтр:

 def name_to_upper(name):
    return name.upper()
class AddForm(FlaskForm):
    name = StringField('Название', filters=[name_to_upper], validators=[DataRequired()])
Выхлоп
     return name.upper()
           ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'upper'

Поле, к которому применяется фильтр, проверяется по POST

 @bp.route('/add', methods=['GET', 'POST'])
def add():
...
    form = AddForm()
    if form.validate_on_submit():
        name = form.name.data
...
demonworm
То есть я понимаю, что к NoneType нельзя применить атрибут upper, вопрос в том, почему он NoneType? Ошибка появляется просто при переходе на страницу /add, то есть до пользовательского ввода и до отправки по кнопке. Класс что ли писать целый для этого, чтобы вставлять callable к объекту класса?
ZerG
Ты создал фильтр - потом применил его
То есть обьект возвращаемый поменялся и для чего тебе еще раз делать upper если фильтр уже и так вернул этот обьект?
Для понимания - в классе убери upper и добавь принты что бы увидеть в кончоли что тебе приходит
 print(name)
print(type(name))
return name
demonworm
Эм. Прошу прощения, это разметка съела пустые строки.

Часть

     return name.upper()
           ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'upper'

это выхлоп. То, что выше, это код.
demonworm
Немного поэксперементировал. Понял, что по какой-то причине фильтр из формы срабатывает два раза: первый раз при переходе на страницу с формой, а второй раз при отправке формы. При переходе на страницу всегда будет передаваться NoneType объект, потому что форма не заполнена, передавать нечего. Обошел хаком

 def name_to_upper(name):
    try:
        return name.upper()
    except (TypeError, AttributeError):
        pass

Как сделать более правильно, пока не знаю.
ZerG
Я именно этого и добивался - что бы вы сами нашли данный момент
Не стесняйтесь пользоваться принтами что бы увидеть что просисходит и что вы получаете
Ведь логично же что при создании у вас будут пустое значение

А вот ваш метод решения не совсем корректен
Либо нужно в саму форму передавать дефолтное значение
либо в функции уже проверять
 if isinstance(name, str):
    return name.upper()
Хотя есть подозрения что вы всеравно какуюто херь делаете - уж очень странный у вас фильтр - разве что только как для теста вы его используете
demonworm
Да, это тестовый фильтр. К сложным пока не перешел, т.к. даже это не работает нормально.

А вот ваш метод решения не совсем корректен
Придерживался принципа “проще попробовать, чем проверять”.

Либо нужно в саму форму передавать дефолтное значение
Это, на мой взгляд, по определению не имеет смысла. Проверять фильтром дефолтное захардкоженое значение… Мне кажется я что-то не так делаю в другом плане.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB