flask-wtf的使用

我们使用django时一般都会用用到django自带的form组件进行登录注册的验证,非常的好用也很强大。flask中同样也有类似的form组件,叫flask-wtf,名字不是很好听,但是功能还是一样的强大。flask-wtf是属于第三方库,需要安装:pip intsall flask-wtf
flask-wtf的使用和django的Form基本类似。
首先创建一个form.py的文件,当然也可以直接将form类写在视图文件里。

from flask_wtf import FlaskForm # 用来定义表单的父类
import wtforms # 可以用来定义字段以及进行表单验证,类似django中的forms

表单常用的字段:

	# StringField  字符串
    # IntegerField  整型
    # TextAreaField  文本
    # PasswordField  密码
    # HiddenField  隐藏域
    # DateField  Datatime.data格式 年月日
    # DateTimeField  Datatime.datatime格式 年月日 时分秒
    # FloatField  小数
    # RadioField  单选
    # SelectField  下拉
    # FileField  文件
    # SubmitField  提交

表单字段常用参数:

	# label = None  字段的标签,即input框前的提示名
    # validators = None  用来储存各种验证器的列表,验证表单数据时会逐一进行调取
    # filters = tuple() 过滤
    # description = ''  字段描述,常用与帮助文档,类似django的django的help_text
    # id = None  为字段添加id值,默认为id为字段名
    # default = None  是一个字符串或可调用对象,为表单字段设置默认值,选择框常用
    # widget = None  html控件,用来定义input框的类型,需要导入widgets
    # render_kw = None  用来设置input框的属性

Validator常用校验:

	# Email  邮件校验
    # EqualTo  比较两个字段的值,常用于密码比较
    # IPAdress  Ipv4格式的IP地址
    # length  长度
    # NumberRange  数字范围
    # DataRequired  空值检查
    # Url  验证是否符合url格式
    # AnyOf  确保输入值在指定范围
    # NoneOf  确保输入的值不在范围

django中可以自定义验证规则,flask-wtf中也不例外,我们可以使用validate_(字段名)进行验证。FlaskForm中还有一些内置的方法,
源码如下:

  def wrap_formdata(self, form, formdata):
       if formdata is _Auto:
           if _is_submitted():
               if request.files:
                   return CombinedMultiDict((
                       request.files, request.form
                   ))
               elif request.form:
                   return request.form
               elif request.get_json():
                   return ImmutableMultiDict(request.get_json())

           return None

    def is_submitted(self):
        """Consider the form submitted if there is an active request and
        the method is ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
        """

        return _is_submitted()

    def validate_on_submit(self):
        """Call :meth:`validate` only if the form is submitted.
        This is a shortcut for ``form.is_submitted() and form.validate()``.
        """
        return self.is_submitted() and self.validate()

    def hidden_tag(self, *fields):
        """Render the form's hidden fields in one call.

        A field is considered hidden if it uses the
        :class:`~wtforms.widgets.HiddenInput` widget.

        If ``fields`` are given, only render the given fields that
        are hidden.  If a string is passed, render the field with that
        name if it exists.

        .. versionchanged:: 0.13

           No longer wraps inputs in hidden div.
           This is valid HTML 5.

        .. versionchanged:: 0.13

           Skip passed fields that aren't hidden.
           Skip passed names that don't exist.
        """

        def hidden_fields(fields):
            for f in fields:
                if isinstance(f, string_types):
                    f = getattr(self, f, None)

                if f is None or not isinstance(f.widget, HiddenInput):
                    continue

                yield f

        return Markup(
            u'\n'.join(text_type(f) for f in hidden_fields(fields or self))
        )

wrap_formdata:获取request中的form数据并返回
is_submitted:判断是否有请求。
validate_on_submit:调用is_submitted()方法和validate()方法,判断表单是否通过验证并且提交,返回一个bool值。
hidden_tag:获取表单的隐藏字段。

使用flask-wtf进行登录验证:
form.py:

from flask_wtf import FlaskForm # 用来定义表单的父类
import wtforms # 可以用来定义字段以及进行表单验证,类似django中的forms
from myblog.models import db,Admin
import hashlib

def setPassword(password):  # 密码加密
    md5 = hashlib.md5()
    md5.update(password.encode())
    f_md5 = md5.hexdigest()
    md5.update(f_md5.encode())
    return md5.hexdigest()


class LoginForm(FlaskForm):
    username = wtforms.StringField(
        label="用户名",
        widget=wtforms.widgets.TextInput(),
        validators=[
            wtforms.validators.DataRequired("用户名不可以为空!"),
            wtforms.validators.Length(8,18,message="用户名必须在8-18位之间!")
        ]
    )
    password = wtforms.PasswordField(
        label="密码",
        widget=wtforms.widgets.PasswordInput(),
        validators=[wtforms.validators.DataRequired("密码不可以为空!")]

    )

    def validate_username(self,field):
        if Admin.query.filter_by(username=field.data).first():
            password = setPassword(self.password.data)
            if password != Admin.query.filter_by(username=field.data).first().password:
                raise wtforms.ValidationError("您输入的用户名或密码错误!")
        else:
            raise wtforms.ValidationError("您输入的用户名或密码错误!")

后台代码:

import hashlib
from myblog.views.form import LoginForm

# cookie加密
def setUsername(username):
    md5 = hashlib.md5()
    md5.update(username.encode())
    return md5.hexdigest()

# 后台登录
@backstage.route("/login/",methods=["get","post"])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        response = redirect("/backstage/")
        username = setUsername(form.username.data)
        response.set_cookie("username",username)
        return response
    return render_template("backstage/login.html",**locals())

前端代码:

<form method="post" action="/login/" novalidate>
   {{ form.csrf_token }}   # 添加csrf_token
    <table >
        <tr>
            <th>{{ form.username.label }}:th>
            <td>{{ form.username }}td>
        tr>
        <tr>
            <th>{{ form.password.label }}:th>
            <td>{{ form.password }}td>
        tr>
    table>
    <div style="color: red"> # 错误信息展示
        {% for error in form.errors.username %}
            <p>{{ error }}p>
        {% endfor %}
        {% for error in form.errors.password %}
            <p>{{ error }}p>
        {% endfor %}
    div>
    <input style="margin-left: 12%" type="submit" value="登录">
form>

页面效果:
flask-wtf的使用_第1张图片
这样就完成了使用falsk-wtf进行登录验证的功能。

你可能感兴趣的:(flask,python)