Вопрос: Использование флагов wtforms валидаторы без использования формы


Я получаю данные регистрации пользователя из приложения iOS, и я хотел бы использовать валидаторы, которые поставляются с wtforms, чтобы убедиться, что адрес электронной почты и пароль являются приемлемыми. Однако я не использую флеш-форму, так как пользователи вводят данные из текстовых полей iOS. Можно ли проверять входящие данные JSON с помощью валидаторов wtforms?

@auth.route('/register', methods=['POST'])
def register():
    try:
        user = User.register_fromJSON(request.json)

        email_success = validate_email(user)
        username_success = validate_username(user)

        if email_success == 1 and username_success == 1:
            db.session.add(user)
            db.session.commit()
            return jsonify({'Success': 1})
        else:
            return jsonify({'Failure': 0})

    except Exception:
        return jsonify({'Failure': 0})

def validate_email(user):
    if User.query.filter_by(email=user.email).first() == None:
        return 1
    else:
        return 0

def validate_username(user):
    if User.query.filter_by(username=user.username).first() == None:
        return 1
    else:
        return 0

РЕДАКТИРОВАТЬ

Я создал регистрационную форму:

class RegistrationForm(Form):
    email = StringField('Email', validators=[Required(), Length(1,64), Email()])
    username = StringField('Username', validators=[Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0, 'Usernames must have only letters, 'numbers, dots or underscores')])
    password = PasswordField('Password', validators=[Required()])


    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first():
            print("Email already registered.")
            raise ValidationError('Email already registered.')

    def validate_username(self, field):
        if User.query.filter_by(username=field.data).first():
            print("Username already in use.")
            raise ValidationError('Username already in use.')

функция регистрации обновлена ​​до:

@auth.route('/register', methods=['POST'])
def register():
    try:
        data = MultiDict(mapping=request.json)
        form = RegistrationForm(data)

        if form.validate():
            user = User.register_fromJSON(request.json)
            db.session.add(user)
            db.session.commit()
            return jsonify({'Success': 1})
        else:
            return jsonify({'Success': 2})

    except Exception:
        return jsonify({'Success': 3})

4


источник


Ответы:


Да, это вполне возможно - wtforms.Form конструктор принимает любой MultiDict подобный интерфейс ( он просто должен иметь getlist), поэтому вы можете просто создать экземпляр werkzeug.datastructures.MultiDict от вашего JSON:

data = MultiDict(mapping=request.json)
form = YourForm(data)
if form.validate():
    # Data is correct

(если имена полей совпадают), и все будет просто работай ,


7



Вот небольшая утилита, называемая Колба-входы  что я работаю над этим. Целью является то, чтобы все входящие данные (формы, запросы, заголовки и т. Д.) Были проверены с помощью валидаторов wtform.

Вот как будет работать валидация с вашими данными:

from flask_inputs import Inputs
from wtforms.validators import Length, Email, ValidationError


class RegisterInputs(Inputs):
    json = {
        'email': [Email(), unique_email],
        'username': [Length(min=3, max=15), unique_username]
    }

def unique_email(form, field):
    if User.query.filter_by(email=field.data).first():
        raise ValidationError('Email is already registered.')

def unique_username(form, field):
    if User.query.filter_by(username=field.data).first():
        raise ValidationError('Username is already registered.')


@auth.route('/register', methods=['POST'])
def register():
    inputs = RegisterInputs(request)

    if inputs.validate():
        user = User.register_fromJSON(request.json)

        db.session.add(user)
        db.session.commit()

        return jsonify(success=1)
    else:
        return jsonify(failure=0, errors=inputs.errors)

1