PYTHON 八月 19, 2019

第5节、Flask表单

文章字数 9.8k 阅读约需 9 mins. 阅读次数 1000000

一、原生表单

1. 添加模板文件login.html,内容如下:

   <form method="post" action="{{ url_for('check') }}">
       用户名:<input name="username" type="text" />
       <input type="submit" value="立即登录" />
   </form>

2. 视图函数,如下:

   # 登录
   @app.route('/login/')
   def login():
       return render_template('login.html')
   P
   # 校验
   @app.route('/check/', methods=['POST'])
   def check():
       print(request.form.get('username'))
       return 'Hello %s !' % request.form['username']

3. 将登录页面和校验的路由合并,如下:

   @app.route('/login/', methods=['GET', 'POST'])
   def login():
       if request.method == 'GET':
           return render_template('login.html')
       else:
           return 'Hello %s !' % request.form['username']

一个路由处理时,表单的action属性不用书写,默认提交到当前路由。

二、flask-wtf处理表单

说明:flask-wtf是一个用于表单处理的扩展库,提供了CSRF、校验等功能,使用非常方便

附:flask-wtf教程

1.跨站请求伪造保护(csrf)

附:浅谈CSRF攻击方式

Flask-WTF 能保护所有表单免受跨站请求伪造(Cross-Site Request Forgery,CSRF)的攻击。恶意网站把请求发送到被攻击者已登录的其他网站时就会引发 CSRF 攻击。为了实现 CSRF 保护,Flask-WTF 需要程序设置一个密钥。Flask-WTF 使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪。

#视图中  设置 Flask-WTF
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'#字典可用来存储框架、扩展和程序本身的配置变量。
#为了增强安全性,密钥不应该直接写入代码,而要保存在环境变量中。

#模板中使用
 {{ form.hidden_tag() }} #或   {{ form.csrf_token }}

2.关闭csrf

@app.route('/form/',methods=['post','get'])
def newform():
    form = NameForm(csrf_enabled = False)

3.flask-wtf常见字段类型和验证器

常见字段类型

字段类型 说明
StringField 普通文本字段
SubmitField 提交按钮
PasswordField 密码文本字段
HiddenField 隐藏文本字段
TextAreaField 多行文本字段
DateField 文本字段,datetime.date格式
DateTimeField 文本字段,datetime.datedatime格式
IntegerField 文本字段,值为整数
FloatField 文本字段,值为小数
BooleanField 复选框,值为True或False
RadioField 单选框
SelectField 下拉框
FileField 文件上传

常见验证器类

验证器 说明
DataRequired 确保字段有值 必填项
Email 邮箱地址 验证邮箱
IPAddress IP地址
Length 规定字符长度 有min和max两个值进行限制。
NumberRange 输入数值的范围
EqualTo 验证两个字段的一致性
URL 有效的URL
Regexp 正则验证
```python
info = TextAreaField(‘个人信息’,render_kw={‘style’:’resize:none;’}) #render_kw 给当前的标签添加属性
```
表单类

每个 Web 表单都由一个继承自Form的类表示。这个类定义表单中的一组字段(表单的内容与类的字段是一一对应的),每个字段都用对象(表单中的对象)表示。字段对象可附属一个或多个验证函数。

4.定义表单类

   # 导入表单基类
   from flask_wtf import FlaskForm
   # 导入字段类型
   from wtforms import StringField, SubmitField
   # 导入验证器类
   from wtforms.validators import DataRequired #必填字段

   # CSRF需要使用
   app.config['SECRET_KEY'] = '123456'

   # 定义表单类 
   class NameForm(FlaskForm):
       #name 为表单的name名称
       name = StringField('用户名', validators=[DataRequired()])
       submit = SubmitField('提交')

5.添加视图函数:

@app.route('/')
def index():
    # 创建表单对象
    form = NameForm()
    # 分配到模板中进行渲染
    return render_template('form.html', form=form)

6.模板文件中渲染表单:

Form 类有一个 hidden_tag 方法, 它在一个隐藏的 DIV 标签中渲染任何隐藏的字段,包括 CSRF 字段:


   <form>

       {{ form.hidden_tag() }} #或   {{ form.csrf_token }}


       {{ form.name.label() }}{{ form.name(id='xxx', class='yyy',style='color:red) }}
       {{ form.name.errors }} #错误提示

       {{ form.submit() }}
   </form>

7.在视图中使用bootstrap的wtf快速渲染表单

#使用bootstrap快速渲染  其它代码不变
from flask_bootstrap import Bootstrap
app.config['BOOTSTRAP_SERVE_LOCAL'] = True #加载本地的js文件
bootstrap = Bootstrap(app)

{% extends 'bootstrap/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{{ wtf.quick_form(form) }}

模板中

更改表单提交地址和表单排列样式

wtf.quick_form(form,form_type='horizontal',action= url_for('login') )

查看都有哪些参数可以查看 wtf.html 里面的 quick_form 宏


   {% extends 'bootstrap/base.html' %}


   {% import 'bootstrap/wtf.html' as wtf %}


   {% block content %}
       
{{ wtf.quick_form(form,action=url_for('upload')) }}
{% endblock %}

8.表单校验

@app.route('/', methods=['GET', 'POST'])
def index():
    # return '表单使用'
    name = None
    # 创建表单对象
    form = NameForm()
    # 表单校验
    #validate_on_submit 会便捷地检查该请求是否是一个 POST 请求以及是否有效。
    if form.validate_on_submit(): 
        name = form.name.data
        form.name.data = ''
    # 分配到模板中进行渲染
    return render_template('form.html', form=form, name=name)

9.自定义表单验证器

自定义字段验证:就是写一个validate_字段名’的函数,如下:

# 定义表单类
class NameForm(FlaskForm):
    name = StringField('用户名', validators=[DataRequired()])
    submit = SubmitField('提交')

    #如果字段中也存在Length对象的验证  那么这俩个验证会重复叠加
    #userName = StringField('用户名',validators=[DataRequired(),Length(3, 6, message='请输入正确的长度')])

    # 自定义字段验证函数,格式是写一个'validate_字段名'的函数 
    def validate_name(self, field):
        if len(field.data) < 6:
            raise ValidationError('用户名长度不能少于6个字符')

10.所有的字段和验证器的使用

class Form(FlaskForm):
    hidde = HiddenField()
    username = StringField('用户名')
    userpass = PasswordField('密码')
    confirm = PasswordField('确认密码',validators=[EqualTo('userpass',message='密码和确认密码不一致')])
    info = TextAreaField('个人信息',render_kw={'style':'resize:none;'})
    birth = DateField('出生年月',format='%Y/%m/%d')
    birthday = DateTimeField('生日日期')
    age = IntegerField('age',validators=[NumberRange(min=6,max=99,message='年龄范围6~99')])
    money = FloatField('money')
    rember = BooleanField('记住我')
    sex = RadioField('sex',choices=[('m','男'),('w','女')])
    address = SelectField('address',choices=[('1001','北京'),('1002','上海'),('1003','深圳')])
    photo = FileField('photo')
    email = StringField('email',validators=[Email(message='请输入合法的邮箱地址')])
    ip = StringField('ip',validators=[IPAddress(message='输入合法的ipv4地址')])
    url = StringField('url',validators=[URL(message='请输入正确的url')])
    phone = StringField('手机号码',validators=[Regexp("[1][3-8][0-9]{9}$",flags=re.I|re.M|re.S,message='输入正确的手机号码')])
    # re.I 不区分大小写
    # re.S 使.匹配换行符
    # re.M 改变 ^ 和 $ 作用 使之可以多行匹配
    submit = SubmitField('submit')
    #自定义表单验证器 validate_ 死的 + 验证的属性名 当点击的时候 就会执行当前的自定义表单验证器
    def validate_username(self,field):
        if self.username.data == 'zhangsan':
            raise ValidationError('当前用户已存在')

上一篇:
下一篇:
0%