flask-wtf表单验证不适用于我的新应用程序

gal*_*lly 1 python flask flask-wtforms

我之前使用过烧瓶,并且我已经进行了工作表单验证,但由于某种原因,它不能用于我的新应用程序.这是表单的基本代码.

from flask.ext.wtf import Form, TextField, TextAreaField, SubmitField, validators,ValidationError

class subReddit(Form):
    subreddit = TextField('subreddit', [validators.Required('enter valid subreddit')])
    next = SubmitField('next')
    change = SubmitField('change')
    user = TextField('user', [validators.Required('enter valid user')])
    fetch = SubmitField('fetch comments')
Run Code Online (Sandbox Code Playgroud)

我有subreddit作为验证字段,所以如果它是空的,我希望它抛出错误并重新加载页面.

HTML:

<form class='sub' action="{{ url_for('sr') }}" method='post'>
  {{ form.hidden_tag() }}                    
  <p>
    if you want to enter more than one subreddit, use the + symbol, like this:
    funny+pics+cringepics
  <p>
    <br/>
    {% for error in form.subreddit.errors %}
  <p>{{error}}</p>
  {% endfor %}
  {{form.subreddit.label}}
  {{form.subreddit}}
  {{form.change}}                    
</form>
Run Code Online (Sandbox Code Playgroud)

我的routes.py中也有CSRF_ENABLED = True.我错过了什么?当我将subredditfield留空并单击更改时,它只是重新加载页面,没有错误.这是一个问题,因为该字段中的任何内容都将记录在我的数据库中,并且它不能为空.

编辑

@app.route('/index',methods=['GET','POST'])
@app.route('/',methods=['GET','POST'])
def index():
form = subReddit()     
rand = random.randint(0,99)
sr = g.db.execute('select sr from subreddit')       
srr = sr.fetchone()[0]
r = requests.get('http://www.reddit.com/r/{subreddit}.json?limit=100'.format(subreddit=srr))
j = json.loads(r.content)     
pic = j['data']['children'][rand]['data']['url'] 
title = None
if form.validate_on_submit():
    g.db.execute("UPDATE subreddit SET sr=(?)", [form.subreddit.data])          
    print 'validate ' 
    if j['data']['children'][rand]['data']['url']:   
        print 'pic real'                
        sr = g.db.execute('select sr from subreddit')       
        srr = sr.fetchone()[0]  
        r = requests.get('http://www.reddit.com/r/{subreddit}.json?limit=100'.format(subreddit=srr))
        pic = j['data']['children'][rand]['data']['url']
        title = str(j['data']['children'][rand]['data']['title']).decode('utf-8')   
        return render_template('index.html',form=form,srr=srr,pic=pic,title=title)
    else:
        print 'not valid pic'
        return render_template('index.html',form=form,srr=srr,pic=pic)
else:
    print 'not valid submit'
    return render_template('index.html',form=form,srr=srr,pic=pic)           
return render_template('index.html',form=form,srr=srr,pic=pic)
Run Code Online (Sandbox Code Playgroud)

Mig*_*uel 8

你有很多问题.

最重要的是验证发生在POST请求视图功能中.在您的示例中,这是功能sr.该函数应该创建表单对象并在将内容添加到数据库之前对其进行验证.

您的代码中的另一个问题(假设上述问题已修复)是​​在验证失败后您重定向.正确的做法是在不重定向的情况下将模板呈现在那里,因为验证产生的错误消息会加载到该表单实例中.如果您重定向,则会丢失验证结果.

另外,使用validate_on_submit而不是validate因为它可以使您不必检查request.method == 'POST'.

例:

@app.route('/sr', methods=['POST'])    
def sr():
    form = subReddit()
    if not form.validate_on_submit():
        return render_template('index.html',form=form)
    g.db.execute("UPDATE subreddit SET sr=(?)", [form.subreddit.data])      
    return redirect(url_for('index'))
Run Code Online (Sandbox Code Playgroud)

其他建议:

  • 通常的做法是使用大写字符启动类名.SubReddit比...更好subReddit.
  • 在同一视图函数中为基于表单的页面提供GET和POST请求处理程序也很常见,因为在验证失败时保持URL清洁,而不必跳过箍以使重定向工作.而不是sr单独使用该功能,您可以将其与index()表单组合并在表单中执行操作url_for('index').