美文网首页
2.8.6Flask --7 Flask的表单操作

2.8.6Flask --7 Flask的表单操作

作者: 寒暄_HX | 来源:发表于2020-03-12 11:30 被阅读0次

    Flask目录:https://www.jianshu.com/p/9b5e30320849

    概述

    flask的表单操作也是依赖于其他组件,我们这里主要讲解Flask-WTF与wftforms。

    Flask-WTF与WTFforms

    安装:python -m pip install Flask-WTF

    Flask-WTF的特点

    避免重复操作, 表单操作很多;
    防止表单遭遇跨站请求伪造(csrf===cross-site request forgery);
    Flask-WTF扩展使得处理web表单能获得更愉快的体验。该扩展是一个封装了与框架无关的WTForms包的Flask集成。

    常用的WTForms字段

    字段 用途
    BooleanField 复选框,值为True或者False
    DateField 文本字段,格式要求为datetime.date一样
    DateTimeField 文本字段,格式要求为datetime.datetime一样
    FloatField 浮点数字段,值是浮点数
    FileField 文件上传字段
    IntergerField 整数字段,格式要求是整数
    RadioField 一组单选框
    SelectField 下拉列表
    SelectMultipleField 多选下拉列表
    SubmitField 提交按钮
    StringField 文本字段
    HiddenField 隐藏文本字段
    PasswordField 密码字段,自动将输入转化为小黑点
    TextAreaField 多行文本字段

    常用参数

    参数 说明
    label 别名
    Validator 校验器
    default 默认值

    校验器常用参数

    __all__ = (
        'DataRequired', 'data_required', 'Email', 'email', 'EqualTo', 'equal_to',
        'IPAddress', 'ip_address', 'InputRequired', 'input_required', 'Length',
        'length', 'NumberRange', 'number_range', 'Optional', 'optional',
        'Required', 'required', 'Regexp', 'regexp', 'URL', 'url', 'AnyOf',
        'any_of', 'NoneOf', 'none_of', 'MacAddress', 'mac_address', 'UUID'
    )
    
    参数 说明
    DataRequired data_required:验证数据是否真实存在,即不能为空,必须是非空白字符串,否则触发StopValidation错误。
    InputRequired input_required:和DataRequired的区别在于可以是空白字符串;
    Required required:data_required的别名
    Email email:验证符合邮件的格式,只有最基本的验证;
    EqualTo equal_to:比较两个字段的值,比如密码和确认密码,如果不相等就触发错误,equal_to(field,message),需要输入另一个字段的名字。
    IPAddress ip_address:验证是否是ip地址,默认验证IPV4地址。
    MacAddress mac_address:验证是否符合mac格式;
    UUID 是否是uuid格式;
    URL url:验证是否符合url格式;
    Regexp regexp:用提供的正则表达式验证字段;Regexp(r"")
    Length length:设置字段值的长度,Length(min,max);
    NumberRange number_range:设置一个数字字段的取值范围,可以针对浮点数和小数;NumberRange(min,max)
    Optional optional:允许字段为空并停止验证;
    NoneOf none_of:将传入的数据和无效的比较,是抛出异常;Noneof(values).
    Anyof any_of:将传入的数据和预设的数据比较,不是异常。Anyof(values).

    登录注册实例

    app.py
    ------
    from flask import Flask, render_template, redirect, url_for
    from flask_sqlalchemy import SQLAlchemy
    
    from forms import LoginForm, UserForm
    
    app = Flask(__name__)
    # 配置数据库的连接参数
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root: @127.0.0.1/test_flasks'
    app.config['WTF_CSRF_SECRET_KEY'] = 'abcd12321'
    app.config['SECRET_KEY'] = 'CCSDFS'
    db = SQLAlchemy(app)
    
    
    class User(db.Model):
        """ 用户ID """
        __tablename__ = 'wei_user'
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(64), nullable=False)
        password = db.Column(db.String(255), nullable=False)
        birth_date = db.Column(db.Date, nullable=True)
        age = db.Column(db.Integer, default=0)
    
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    #登录
    @app.route('/user', methods=['GET', 'POST'])
    def form_user():
        """ 登录 """
        form = LoginForm()
        if form.validate_on_submit():
            # 获取表单数据
            username = form.username.data
            password = form.password.data
            user = db.session.query(User).filter_by(username=username,password=password).first()
            if user:
                # 提示/跳转
                print('登录成功')
                return redirect(url_for('index'))
        else:
            print('表单验证未通过')
            print(form.errors)
        return render_template('form.html', form=form)
    
    #注册
    @app.route('/user/add', methods=['GET', 'POST'])
    def add_user():
        """ 注册 """
        form = UserForm()
        if form.validate_on_submit():
            # 获取表单数据
            username = form.username.data
            password = form.password.data
            birth_date = form.birth_date.data
            age = form.age.data
            # 保存到数据
            user = User(username=username,
                        password=password,
                        birth_date=birth_date,
                        age=age)
            db.session.add(user)
            db.session.commit()
            # 提示/跳转
            print('添加成功')
            return redirect(url_for('index'))
        else:
            print('表单验证未通过')
            print(form.errors)
        return render_template('add_user.html', form=form)
    
    form.py
    -------
    from flask_wtf import FlaskForm
    from wtforms import StringField, PasswordField, SubmitField, DateField, IntegerField
    
    
    class LoginForm(FlaskForm):
        """ 用户登录 """
        username = StringField(label='用户名')
        password = PasswordField(label='密码')
    
        submit = SubmitField('登录')
    
    
    class UserForm(FlaskForm):
        """ 新增用户 """
    
        username = StringField(label='用户名')
        password = PasswordField(label='密码')
    
        birth_date = DateField(label='生日')
        age = IntegerField(label='年龄')
    
        submit = SubmitField('新增')
    
    form.html
    ---------
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单的使用</title>
    </head>
    <body>
    <form action="{{ url_for('form_user') }}" method="post">
        {{ form.csrf_token }}
    
        <p>{{ form.username.label }}:{{ form.username }}</p>
        <p>{{ form.password.label }}:{{ form.password }}</p>
        {{ form.submit }}
    </form>
    </body>
    </html>
    
    
    
    add_user.html
    -------------
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加新用户</title>
    </head>
    <body>
    <form action="{{ url_for('add_user') }}" method="post">
        {{ form.csrf_token }}
        <p>
            {{ form.username.label }}
            {{ form.username }}
        </p>
        <p>
            {{ form.password.label }}
            {{ form.password }}
        </p>
        <p>
            {{ form.birth_date.label }}
            {{ form.birth_date }}
        </p>
        <p>
            {{ form.age.label }}
            {{ form.age }}
        </p>
        <p>
            {{ form.submit }}
        </p>
    </form>
    </body>
    </html>
    

    登录注册校验实例

    import re
    from flask_wtf import FlaskForm
    from wtforms import StringField, PasswordField, SubmitField, DateField, IntegerField
    from wtforms.validators import DataRequired, ValidationError
    
    
    def phone_required(form, field):
        """ 自定义的验证 """
        username = field.data
        # 强制用户名为手机号码
        pattern = r'^1[0-9]{10}$'
        if not re.search(pattern, username):
            raise ValidationError('请输入手机号码')
        return field
    
    
    class LoginForm(FlaskForm):
        """ 用户登录 """
        username = StringField(label='用户名', validators=[
            phone_required
        ])
        password = PasswordField(label='密码')
    
        submit = SubmitField('登录')
    
    
    class UserForm(FlaskForm):
        """ 新增用户 """
    
        username = StringField(label='用户名', validators=[
            phone_required
        ])
        password = PasswordField(label='密码')
    
        birth_date = DateField(label='生日', validators=[DataRequired('请输入生日')])
        age = IntegerField(label='年龄')
    
        submit = SubmitField('新增')
    
    add_user.html
    --------------
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加新用户</title>
    </head>
    <body>
    <form action="{{ url_for('add_user') }}" method="post" novalidate>
        {{ form.csrf_token }}
        <p>
            {{ form.username.label }}
            {{ form.username }}
            {% if form.username.errors %}
                {% for err in form.username.errors %}
                    {{ err }}
                {% endfor %}
            {% endif %}
        </p>
        <p>
            {{ form.password.label }}
            {{ form.password }}
        </p>
        <p>
            {{ form.birth_date.label }}
            {{ form.birth_date }}
        </p>
        <p>
            {{ form.age.label }}
            {{ form.age }}
        </p>
        <p>
            {{ form.submit }}
        </p>
    </form>
    </body>
    </html>
    

    文件上传

    我们接着用两个实例来演示,第一个实例是使用form表单实现:

    import os
    
    from flask import Flask, render_template,request
    from werkzeug.utils import secure_filename
    
    app = Flask(__name__)
    app.config['UPLOAD_PATH'] = os.path.join(os.path.dirname(__file__), 'medias')
    
    @app.route('/img/upload', methods=['GET', 'POST'])
    def img_upload():
        """ 图片上传 """
    
        if request.method == 'POST':
            # 取文件
            files = request.files
            file1 = files['file1']
            # 保存文件
            if file1:
                # 文件名称格式化
                filename = secure_filename(file1.filename)
                file_name = os.path.join(app.config['UPLOAD_PATH'], filename)
                file1.save(file_name)
        return render_template('img_upload.html')
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>图片上传</title>
    </head>
    <body>
    <form action="{{ url_for('img_upload') }}" method="post" enctype="multipart/form-data">
        <input type="file" name="file1">
        <input type="submit" value="点击上传">
    </form>
    </body>
    </html>
    

    第二种是使用了flask-wtf:

    import os
    
    from flask import Flask, render_template,request
    from werkzeug.utils import secure_filename
    
    from forms import UserAvatarForm
    
    app = Flask(__name__)
    app.config['UPLOAD_PATH'] = os.path.join(os.path.dirname(__file__), 'medias')
    
    @app.route('/avatar/upload', methods=['GET', 'POST'])
    def avatar_upload():
        """ 头像上传 """
        form = UserAvatarForm()
        if form.validate_on_submit():
            f = form.avatar.data
            filename = secure_filename(f.filename)
            file_name = os.path.join(app.config['UPLOAD_PATH'], filename)
            f.save(file_name)
            print('上传头像成功')
        else:
            print(form.errors)
        return render_template('avatar_upload.html', form=form)
    
    
    form.py
    -------
    import re
    from flask_wtf import FlaskForm
    from flask_wtf.file import FileRequired, FileAllowed, FileField
    
    class UserAvatarForm(FlaskForm):
        avatar = FileField(label='上传头像', validators=[
            FileRequired('请选择图片文件'),
            FileAllowed(['png'], '仅支持png')
        ])
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>头像上传</title>
    </head>
    <body>
        <form action="{{ url_for('avatar_upload') }}" method="post" enctype="multipart/form-data">
        {{ form.avatar }}
         {{ form.csrf_token }}
        <input type="submit" value="点击上传">
    </form>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:2.8.6Flask --7 Flask的表单操作

          本文链接:https://www.haomeiwen.com/subject/iobcjhtx.html