Форум сайта python.su
Здравствуйте.
Подскажите, как правильно писать фильтры для 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'
@bp.route('/add', methods=['GET', 'POST']) def add(): ... form = AddForm() if form.validate_on_submit(): name = form.name.data ...
Отредактировано demonworm (Окт. 19, 2023 12:11:09)
Офлайн
То есть я понимаю, что к NoneType нельзя применить атрибут upper, вопрос в том, почему он NoneType? Ошибка появляется просто при переходе на страницу /add, то есть до пользовательского ввода и до отправки по кнопке. Класс что ли писать целый для этого, чтобы вставлять callable к объекту класса?
Офлайн
Ты создал фильтр - потом применил его
То есть обьект возвращаемый поменялся и для чего тебе еще раз делать upper если фильтр уже и так вернул этот обьект?
Для понимания - в классе убери upper и добавь принты что бы увидеть в кончоли что тебе приходит
print(name) print(type(name)) return name
Отредактировано ZerG (Окт. 19, 2023 11:40:45)
Офлайн
Эм. Прошу прощения, это разметка съела пустые строки.
Часть
return name.upper() ^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'upper'
Офлайн
Немного поэксперементировал. Понял, что по какой-то причине фильтр из формы срабатывает два раза: первый раз при переходе на страницу с формой, а второй раз при отправке формы. При переходе на страницу всегда будет передаваться NoneType объект, потому что форма не заполнена, передавать нечего. Обошел хаком
def name_to_upper(name): try: return name.upper() except (TypeError, AttributeError): pass
Офлайн
Я именно этого и добивался - что бы вы сами нашли данный момент
Не стесняйтесь пользоваться принтами что бы увидеть что просисходит и что вы получаете
Ведь логично же что при создании у вас будут пустое значение
А вот ваш метод решения не совсем корректен
Либо нужно в саму форму передавать дефолтное значение
либо в функции уже проверять
if isinstance(name, str): return name.upper()
Офлайн
Да, это тестовый фильтр. К сложным пока не перешел, т.к. даже это не работает нормально.
А вот ваш метод решения не совсем корректенПридерживался принципа “проще попробовать, чем проверять”.
Либо нужно в саму форму передавать дефолтное значениеЭто, на мой взгляд, по определению не имеет смысла. Проверять фильтром дефолтное захардкоженое значение… Мне кажется я что-то не так делаю в другом плане.
Офлайн