《Python Web开发实战》踩地雷记17/3/26

本文介绍如何使用Flask-WTF扩展简化Web表单处理流程,并提供了从配置CSRF保护到视图函数中处理表单提交的完整示例。

Linux修改文件名:mv [文件名1] [文件名2]
1.Flask-WTF
Flask-WTF扩展可以把处理Web表单的过程编程一种愉快的体验。这个扩展对独立的WTForms包进行了包装,方便集成到Flask程序中。

pip install flask-wtf

2.跨站请求伪造保护
默认情况下,Flask-WTF能保护所有表单面免受跨站请求伪造(Cross-Site Request Forgery,CSRF)的攻击。恶意网站把请求发送到被攻击者已登录的其他网站是就会引发CSRF攻击。

为了实现CSRF保护,Flask-WTF需要程序设置一个密钥。Flask-WTF使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪。

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key'

3.表单类
使用Flask-WTF时,每个Web表单都由一个继承自Form的类表示,这个类定义表单中的一组字段,每个字段都用对象表示,字段对象可附属一个或多个验证函数。
hello.py:定义表单类

from flask_wtf import Form
from wtforms import StringField,SubmitField
from wtforms.validators import Required
class NameForm(Form):
    name = StringField('你的名字?',validators=[Required()])
    submit = SubmitField('提交')

index.html:渲染表单

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}


{% block title %}Flasky{% endblock %}

{% block page_content %}

<div class="page-header">
{% if name %}
    <h1> Hello,{{ name }}! </h1>{% else %}<h1>Hello,Stranger!</h1>
{% endif %}
</div>

{{ wtf.quick_form(form) }}

{% endblock %}

Flask-Bootstrap提供了一个非常高端的辅助函数,可以使用Bootstrap中预先定义好的表单演示渲染整个Flask-WTF表单,而这些操作只需一次调用即可完成。wtf.quick_form()函数的参数为Flask-WTF表单对象,使用Bootstrap样式渲染传入的表单。
4.在视图函数中处理表单
视图函数index()要接收表单中的数据
hello.py:路由方法

@app.route('/',methods=['GET','POST'])
def index():
    name = None
    nameForm = NameForm()

    if nameForm.validate_on_submit():
        name = nameForm.name.data
        nameForm.name.data = ''

    return render_template('index.html',form=nameForm,name=name)

app.route修饰器中添加的methods参数告诉Flask在URL映射中把这个视图函数注册为GET和POST请求的处理程序,如果没有指定methods参数,就只把视图函数注册为GET请求处理程序。因为Web表单提交为POST方式,故需要显示标明

GET 浏览器告知服务器:只 获取 页面上的信息并发给我。这是最常用的方法。
POST 浏览器告诉服务器:想在 URL 上 发布新信息。并且,服务器必须确保 数据已存储且仅存储一次。这是 HTML 表单通常发送数据到服务器的方法。

5.重定向和用户会话
重定向是一种特殊的响应,响应内容是URL,而不是包含HTML代码的字符串,为了不让Web程序把POST请求作为浏览器发送的最后一个请求,使用重定向解决重复提交出现弹框问题。
hello.py:重定向和用户会话

 from flask import Flask,render_template,session,url_for,redirect
 @app.route('/',methods=['GET','POST'])
def index():
    name = None
    nameForm = NameForm()

    if nameForm.validate_on_submit():
        session['name'] = nameForm.name.data
        nameForm.name.data = ''
        return redirect(url_for('index'))

    return render_template('index.html',form=nameForm,name=session.get('name'))

redirect()函数的参数是重定向的URL,使用url_for()生成URL映射生成URL,从而保证URL和定义的路由兼容,而且修改路由名字后依然可用
6.Flash消息
hello.py:Flash消息

from flask import Flask,render_template,session,url_for,redirect,flash
@app.route('/',methods=['GET','POST'])
def index():
    form = NameForm()

    if nameForm.validate_on_submit():
        old_name=session.get('name')

        if old_name is not None and old_name != form.name.data:
            flash('name changed')
        session['name'] = nameForm.name.data
        return redirect(url_for('index'))
    return render_template('index.html',form=nameForm,name=session.get('name'))

base.html:渲染Flash消息

{% block content %}

<div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{ message }}
    </div>
    {% endfor %}

  {% block page_content %}{% endblock %}
</div>

{% endblock %}

遇到的问题:
1.定义表单类时

 class NameForm(Form):
    name = StringField('你的名字?',validators=[Required()])
    submit = SubmitField('提交')

这里的Form要用flask_wtf.FlaskForm替换
Warning: flask_wtf.Form has been renamed to “FlaskForm”
2.遇到错误

File”/home/shitfly/webgo/venv/local/lib/python2.7/site-packages/wtforms/validators.py”,line220,in__init__super(Required, self).init(*args, **kwargs)
TypeError: init() takes at most 2 arguments (3 given)

原因:name=StringField('What is your name?',validators=[Required()])未加()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值