flask-wtf扩展

表单处理扩展

Flask-WTF

文档

该扩展提供了WTForms的集成。文档已经相当详尽地为我们讲述了如何使用。

安装使用

pip install Flask-WTF

我们需要在项目里创建一个单独的form模块进行我们表单的创建和验证等。

为了能让所有视图可以受到CSRF保护。

# form/__init__.py
from flask_wtf import CSRFProtect
from App import app


csrf = CSRFProtect(app)

除了常规的HTML表单,包括HTML5新表单类型,文件上传,都可以很好的支持。

比如:一个带有时间选择,文件上传的表单:

from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField,TextAreaField,DateField
from wtforms.validators import DataRequired,Length
from flask_wtf.file import FileField,FileAllowed,FileRequired
from App import photos

class PostForm(FlaskForm):
    post_img = FileField(validators=[FileAllowed(photos,'only images'),FileRequired()])
    title = StringField('Title',validators=[DataRequired(),Length(min=0,max=12)])
    time = DateField('Time',validators=[DataRequired()])
    address = StringField('Address',validators=[DataRequired(),Length(max=24)])
    content = TextAreaField('Write',validators=[DataRequired(),Length(max=300)]) 
    submit = SubmitField('Submit')

视图:实例化出的form对象,我们可以在这里进行获取表单内容和进行验证。

@post.route('/new',methods=['GET','POST'])
@login_required
def new():
    form = PostForm()
    if form.validate_on_submit():
        try:
            post = Post(
                title=form.title.data,
                content=form.content.data,
                post_img=upload_img(form.post_img.data,before=None,not_s=True),
                time=form.time.data,
                address=form.address.data,
                user_id=current_user.id
            )
            db.session.add(post)
            db.session.commit()
            flash("成功")
            return redirect(url_for('main.home'))
        except:
            flash('Error')
            db.session.rollback()
    return render_template(
        'add_post.html',
        title='新动态',
        form=form,
        year=datetime.now().year
    )

模版文件:

我们需要进行指定表单enctype="multipart/form-data"

指定我们渲染表单字段的宏

{% macro render_field(field) %}
<div class="form-group">
    {{field.label}}
    {{ field( **kwargs ) }}
    <small class="text-muted error">
        {% for error in field.errors %}
        {{error}}
        {% endfor %}
    </small>
</div>
{% endmacro %}
{% from 'function.html' import render_field %}

<form method="POST" enctype="multipart/form-data">

    {{ form.hidden_tag() }}
    
    {{render_field(form.title)}}
    
    <div class="form-group">
    {{ form.time( class="validate",type="date" ) }}
    <small class="text-muted fg-crimson">
    {% for error in form.time.errors  %}
    	{{error}}
    {% endfor %}
    </small>
    </div>
    
    {{render_field(form.address)}}
    
    {{render_field(form.content)}}
    
    {% if post_img_src %}
    <div class="input-wrapper">
    <div class="image-label">
    <img src="{{post_img_src}}"/>
    </div>
    </div>
    {% endif %}
    
    <div class="input-wrapper">
    <label class="image-label" for="post_img" id="poster">
    {{ form.post_img( 
    	class="image-hidden-input",
    	onchange="getPhoto(this)", 
    	accept=".jpeg, .jpg, .png" 
    )}}
    <span id="upload-text">封面</span>
    </label>
    <small class="text-muted error">
    {% for error in form.post_img.errors  %}
    {{error}}
    {% endfor %}
    </small>
    </div>
    
    <div class="form-group">
    {{form.submit()}}
    </div>

</form>

简单实现了表单的使用。

如果通过ajax进行数据提交或者进行其他操作时,我们也需要传输csrf_token来进行操作验证。

推荐方式是在模版头部添加一个meta字段,让进行ajax时将数据从头部带到后端。

<meta name="csrf-token" content="{{ csrf_token() }}">

或者直接在脚本中进行渲染。

function del(href){
	if (confirm('确定删除?')){
			// 渲染csrf_token
			var csrftoken = "{{ csrf_token() }}"
			$.ajax({
				method: "DELETE",
				url: href,
				headers:{
					"X-CSRFToken": csrftoken
				},
				onSuccess: function(response){
					console.log(response);
					window.location.reload();
				},
					onFail: function(xhr){
						console.log(xhr);
					}
				});
		}
	}
</script>


奖励一下