【问题标题】:Flask - WTForm - save form to dbFlask - WTForm - 将表单保存到数据库
【发布时间】:2014-01-17 04:49:34
【问题描述】:

我在将表单 (wtf) 保存到 (sqlalchemy) db 时遇到问题,表单正在呈现,但提交后没有任何反应......

例如:

127.0.0.1 - - [30/Dec/2013 10:30:24] "POST /add/ HTTP/1.1" 200 -

我试图在没有验证器的情况下保存

例如:

name = TextField('Task Name')

我试图以其他方式保存表单:

if request.method == 'POST' and form.validate():
            new_task = Tasks(
                         form.name.data,
                         form.due_date.data,
                         form.priority.data,
                         form.posted_date.data,
                         session['user_id'],
                         form.category.data,
                         form.super_category.data,
                         form.description.data
                        )
            db.session.add(new_task)
            db.session.commit()  

下面的代码:

型号:

# -*- coding: utf-8; -*-

from app import db
import datetime


class Tasks(db.Model):

    __tablename__ = "tasks"

    task_id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(255),nullable=False)
    description = db.Column(db.Text,nullable=False)
    priority = db.Column(db.Integer,nullable=False)
    posted_date = db.Column(db.DATE,nullable=False)
    status = db.Column(db.Integer,default=1,nullable=False)
    category = db.Column(db.String(255),nullable=False)
    super_category = db.Column(db.String(255),nullable=False)
    user_id = db.Column(db.Integer,db.ForeignKey('users.id'))

    def __init__(self,name,due_date,priority,posted_date,users_id,category,super_category,description):
        self.name = name
        self.due_date = due_date
        self.priority = priority
        self.posted_date = posted_date
        self.user_id = users_id
        self.category = category
        self.super_category = super_category
        self.description = description

表格:

 # -*- coding: utf-8; -*-
from wtforms import Form,validators
from wtforms import TextField,DateField,IntegerField,SelectField,TextAreaField
from wtforms.validators import required,Email,EqualTo,Length
from wtforms import PasswordField

class AddTask(Form):
  name = TextField('Task Name',validators=[required()])
  due_date = DateField('Date Due (mm/dd/yyyy)',validators=[required()],format='%m/%d/%Y')
  priority = SelectField('Priority',validators=[required()],choices=[('1','1'),('2','2'),('3','3'),('4','4'),('5','5')])
  description = TextAreaField('Description',validators=[required()])
  posted_date = DateField('Posted Date (mm/dd/yyyy)',validators=[required()],format='%m/%d/%Y')
  category = SelectField('Category',validators=[required()],choices=[('foobar','foobar'),('foobar2','foobar2')])
  super_category = SelectField('Super_category',validators=[required()],choices=[('foobar3','foobar3'),('foobar4','foobar4'),('foobar5','foobar5')])
  user_id = SelectField('User',validators=[required()],choices=[('1','1'),('2','2'),('3','3'),('4','4'),('5','5')])

浏览量:

@app.route('/add/',methods=['GET','POST'])
@login_required
def new_task():
    form = AddTask(request.form,csrf_enabled=True)
    if request == 'POST' and form.validate():
        form_tasks = Tasks()
        form.populate_obj(form_tasks)
        db.session.add(form_tasks)
        db.session.commit()
        return redirect(url_for('tasks'))
    return render_template('form.html',form=form)

form.html:

{% extends "layout2.html" %}
{% from 'common.html' import edit_field %}
{%  block content %}
<div class='edit well offset 2 span8'>
  <form method='post' class="form-horizontal">
    <legend> Add task </legend>
        {{ edit_field(form.name , class="span3") }}
        {{ edit_field(form.due_date , class="span3", type="datetime") }}
        {{ edit_field(form.priority, class="span3") }}
        {{ edit_field(form.description, rows="5" ,class="span3", placeholder="foobar" ) }}
        {{ edit_field(form.posted_date, class="span3",type="datetime") }}
        {{ edit_field(form.category, class="span3") }}
        {{ edit_field(form.super_category, class="span3") }}
<div class="form-actions">
<button type="submit" class="btn">SAVE</button>
</div>
</form>
</div>
{%  endblock    %}

common.html:

{% macro edit_field(field,catch_kwargs=true) %}
<div class="control-group{% if field.errors  %} error {% endif %}">
    {{  field.label(class="control-label") }}
<div class="controls">
    {{  field(**kwargs)  }}
    {% for error in field.errors %}
    <span class="help-inline">{{error}}</span>
    {% endfor %}
</div>
</div>
{% endmacro %}

【问题讨论】:

  • 如有疑问,请登录form.errors

标签: python flask flask-sqlalchemy wtforms flask-wtforms


【解决方案1】:

您需要在表单中的某处放置防伪令牌。 在您的模板文件中的表单标签内添加以下内容:

{{ form.hidden_tag() }}

这使得隐藏字段类似于

<input id="csrf_token" name="csrf_token" type="hidden" value="xxxxxx">

将它与我们得到的 form.html 文件放在一起:

{% extends "layout2.html" %}
{% from 'common.html' import edit_field %}
{% block content %}
<div class='edit well offset 2 span8'>
    <form method='post' class="form-horizontal">
        {{ form.hidden_tag() }}
        <legend>Add task</legend>
        {{ edit_field(form.name , class="span3") }}
        {{ edit_field(form.due_date , class="span3", type="datetime") }}
        {{ edit_field(form.priority, class="span3") }}
        {{ edit_field(form.description, rows="5" ,class="span3"
                     , placeholder="foobar" ) }}
        {{ edit_field(form.posted_date, class="span3",type="datetime") }}
        {{ edit_field(form.category, class="span3") }}
        {{ edit_field(form.super_category, class="span3") }}
        <div class="form-actions">
            <button type="submit" class="btn">SAVE</button>
        </div>
    </form>
</div>
{% endblock %}

【讨论】:

    【解决方案2】:

    解决办法是:

    添加 hidden_tag() - 谢谢 vittore !

    flask_wtf 而不是从 wtforms 导入“表单”。

    new_task()中删除“request.form”

    现在代码看起来像这样并且它正在工作! - 谢谢大家的帮助。

    @app.route('/add/',methods=['GET','POST'])
    @login_required
    def new_task():
        form = AddTask(csrf_enabled=True)
        if form.validate_on_submit():
            new_task = Tasks(
                              form.name.data,
                              form.due_date.data,
                              form.priority.data,
                              form.posted_date.data,
                              session['user_id'],
                              form.category.data,
                              form.super_category.data,
                              form.description.data
                            )
            db.session.add(new_task)
            db.session.commit()
            return redirect(url_for('tasks'))
        else:
            flash_errors(form)
        return render_template('form.html',form=form)
    

    【讨论】:

    • 嗨@Mammoth,欢迎来到社区。我看到你是新来的,所以想建议礼貌的做法是接受 vittore 的回答。我相信您甚至可以用您的解决方案更新他的回复。
    • 嗨@jwogrady,我接受了维托雷的回答——但我不知道如何更新他的回答:))
    【解决方案3】:

    看起来您的 form.validate() 正在返回 False,请尝试在没有验证检查的情况下进行测试,看看会发生什么,我也没有看到 csrf 令牌在任何地方传递。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 2016-10-15
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 1970-01-01
      相关资源
      最近更新 更多