Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 16, 2015 14:27:30

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

from flask_wtf import Form
from wtforms import StringField
class EquipmentAddForm(Form):
    main_ip = TextField(
        label=u'IP-адрес',
        validators=[IPAddress(message=u'Неправильный ip-адрес')]
    )
    def validate_main_ip(self, field):
        # Введен неправильный ip-адрес
        # Приходится вызывать field.validate второй раз
        if not field.validate(self):
            return
        # Проверяем `существует ли такой ip-адрес
        if db.session.query(exists()\
                .where(Host.addr == field.data))\
                .scalar():
            raise ValidationError(u'Этот ip-адрес занят.')

Сначала проверяется, что введенное поле является ip-адресом, затем, если это так, проверяется в базе не занят ли данный ip-адрес. Данный код работает и делает, что нужно, но проблема в том, что field.validate здесь выполнится два раза. Если же я уберу field.validate из validate_main_ip, то будет попытка проверки в базе для неправильного ip-адреса. Как мне тут поступить? Неужели только переопределять метод validate у формы? Нет способа реализовать также как в Django?



Офлайн

#2 Дек. 16, 2015 15:28:09

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

Откройте любой валидатор и посмотрите как он пишется…

wtforms-alchemy не помешает посмотреть на досуге

Отредактировано 4kpt_III (Дек. 16, 2015 15:35:51)

Офлайн

#3 Дек. 17, 2015 05:51:29

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

4kpt_III
Откройте любой валидатор и посмотрите как он пишется…wtforms-alchemy не помешает посмотреть на досуге
Я и валидаторы смотрел и код формы, отвечающий за валидацию смотрел, но так и не нашел ответа на вопрос, как сделать так, чтобы кастомный валидатор выполнялся только если пройдет проверку встроенный. Если вам несложно напишите код, решающий мою задачу. На всякий случай напомню:
В форме нужно проверить, что поле является ip-адресом и что этот ip-адрес не занят(не присутствует в таблице).
Как бы вы это реализовали?
4kpt_III
wtforms-alchemy не помешает посмотреть на досуге
Смотрел как раз таки на досуге, только не нашел, чем они могут мне помочь.



Офлайн

#4 Дек. 17, 2015 10:42:31

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

plusplus
валидаторы “validate_<some_name>” добавляются в конец списка валидаторов

Офлайн

#5 Дек. 17, 2015 11:44:12

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

sander
plusplusвалидаторы “validate_<some_name>” добавляются в конец списка валидаторов
Никто не спорит.

Я уже не знаю как объяснить еще проще. Мой пример, поле main_ip. Пользователь вводит ерунду, типа “абырвалг”, валидатор IPAddress сработает, добавит ошибку в форму, всё ок. НО, валидатор validate_main_ip ЗАПУСТИТСЯ всё равно, полезет в базу и выполнит запрос с параметром “абырвалг”, который в свою очередь выдаст ошибку, т.к. поле в базе не текстовое и делать к нему запрос можно только с ip-адресом. Как этого избежать?



Отредактировано plusplus (Дек. 17, 2015 11:46:05)

Офлайн

#6 Дек. 17, 2015 11:56:48

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

plusplus
такое может произойти только если поле пустое, добавь validators.DataRequired() самым первым

Офлайн

#7 Дек. 17, 2015 12:10:06

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

plusplus
Смотрел как раз таки на досуге, только не нашел, чем они могут мне помочь.

Значит плохо смотрели

Офлайн

#8 Дек. 17, 2015 12:40:24

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

sander
plusplusтакое может произойти только если поле пустое, добавь validators.DataRequired() самым первым
Причем тут DataRequired? Вот ошибка, для непустого поля, но с неправильным вводом, если убрать проверку field.validate(self) из кастомного валидатора

sqlalchemy.exc.DataError
DataError: (DataError) invalid input syntax for type inet: "fsdsadf"
LINE 3: WHERE hosts.addr = 'fsdsadf') AS anon_1
                           ^
 'SELECT EXISTS (SELECT * \nFROM hosts \nWHERE hosts.addr = %(addr_1)s) AS anon_1' {'addr_1': u'fsdsadf'}



Отредактировано plusplus (Дек. 17, 2015 12:40:46)

Офлайн

#9 Дек. 17, 2015 13:23:27

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

plusplus
у тебя 2 варианта:
1) переписать метод __call__ у IPAddress валидатора что бы он выбрасывал StopValidation вместо ValidationError
2) проверять наличие ошибок в field.errors

Офлайн

#10 Дек. 17, 2015 13:45:43

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

Свой валидатор в wtforms, flask

sander
2) проверять наличие ошибок в field.errors

О точно, спасибо.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version