使用SQLAlchemy对象中的数据预填充烧瓶中的WTforms

时间:2014-05-17 15:20:04

标签: python flask flask-sqlalchemy flask-wtforms

我对于flask框架相当新,并且正在为webportal创建一个编辑个人资料页面。我陷入困境,无法自动填写表格。

这是我的表单类:

class EditProfile(Form):

    username = TextField('Username', [Required()])
    email = TextField('Email', [Required()])
    about = TextAreaField('About', [Required()])
    website = TextField('Website', [Required()])

这是我评估表单的函数。

def editprofile(nickname = None):
    if g.fas_user['username'] == nickname  or request.method == 'POST':
        form = EditProfile()
        form_action = url_for('profile.editprofile')
        if request.method == 'POST' and form.validate():
            if form.username.data == nickname : 
              query = EditProfile(form.username.data,
                                 form.email.data,
                                 form.about.data,
                                 form.website.data,
                                 )
              print query #debug
              db.session.add(query)
              db.session.commit()
              flash('User Updated')
              print "added"
            return(url_for('profile.editprofile'))
        return render_template('profile/add.html', form=form,
                               form_action=form_action, title="Update Profile")
    else:
        return "Unauthorised"

我的表单形式的html模板是:

{% extends "base.html" %}
    {% block title %}
        {{ title }}
    {% endblock %}
    {% block content %}
    {% from "_formhelpers.html" import render_field %}
    <div id="Edit Profile">
        <h2>{{  title  }}</h2>
        <form method="post" action="{{ form_action }}">
            <fieldset>
                <legend></legend>
                {{ render_field(form.username) }}
                {{ render_field(form.email)}}
                {{ render_field(form.about )}}
                {{ render_field(form.website) }}
            </fieldset>
        <input type="submit" class="button" value="Save"/>
    </form>
    </div>
    {% endblock %}


我有一个用户类的对象。从该对象我想预先填写此表单。如何预填充表单中的值。我想在这里实现编辑配置文件功能。

3 个答案:

答案 0 :(得分:17)

您需要在创建表单时将对象传递给表单。

form = EditProfile(obj=user)  # or whatever your object is called

你将遇到麻烦

          query = EditProfile(form.username.data,
                             form.email.data,
                             form.about.data,
                             form.website.data,
                             )
          db.session.add(query)

它会创建EditProfile表单的新实例。然后,您尝试将其添加到会话中。会议需要模型,而不是表格。

相反,在验证表单后,您可以将其值与对象关联。

form.populate_obj(user)  # or whatever your object is called

由于您的对象已加载,因此您无需将其添加到会话中。您可以删除db.session.add(query),然后只需致电db.session.commit()

答案 1 :(得分:6)

我发现这样做的最简单方法是在get请求中填写表单字段。

@decorator_authorized_user  # This decorator should make sure the user is authorized, like @login_required from flask-login
def editprofile(nickname = None):
    # Prepare the form and user
    form = EditProfile()
    form_action = url_for('profile.editprofile')
    my_user = Users.get(...)  # get your user object or whatever you need
    if request.method == 'GET':
        form.username.data = my_user.username
        form.email.data = my_user.email
        # and on
    if form.validate_on_submit():
        # This section needs to be reworked.
        # You'll want to take the user object and set the appropriate attributes
        # to the appropriate values from the form.
        if form.username.data == nickname: 
            query = EditProfile(form.username.data,
                                form.email.data,
                                form.about.data,
                                form.website.data,
                                )
            print query #debug
            db.session.add(query)
            db.session.commit()
            flash('User Updated')
            print "added"
            return(url_for('profile.editprofile'))
    return render_template('profile/add.html', form=form,
                           form_action=form_action, title="Update Profile")

这将设置函数以在get请求中返回预填充表单。您必须重新修改form.validate_on_submit下的部分。 Dirn的回答表明了一些正确的事情。

答案 2 :(得分:6)

使用SQLAlchemy对象填充表单:

color: 1 numLanesLeft: 16 
color: 2 numLanesLeft: 15 
color: 1 numLanesLeft: 14 
color: 2 numLanesLeft: 12 
color: 1 numLanesLeft: 12 
color: 2 numLanesLeft: 11 
color: 1 numLanesLeft: 10 
color: 2 numLanesLeft: 9 
color: 1 numLanesLeft: 9 
color: 2 numLanesLeft: 8 
color: 1 numLanesLeft: 7 
color: 2 numLanesLeft: 6 
color: 1 numLanesLeft: 5 
color: 2 numLanesLeft: 4 
color: 1 numLanesLeft: 3 
color: 2 numLanesLeft: 2 
color: 1 numLanesLeft: 1 

如果您的表单字段由于某种原因(它们应该)而与模型中的数据库列不匹配,那么表单类将使用kwargs:

  

** kwargs - 如果formdata或obj都不包含字段的值,则表单将为匹配的关键字参数赋值   字段,如果提供的话。

我发现一个用例就是如果你有一个包含引用多个模型的字段的表单(例如通过关系);传递一个form = EditProfile(obj=<SQLAlchemy_object>) 还不够。

因此,让我们举例说明您的数据库模型(obj),使用user代替site(表单字段名称)。您这样做是为了从SQLAlchemy对象填充表单:

website

然后在POST中你必须这样做才能从你的表单中填充你的SQLAchemy对象:

form = EditProfile(obj=user, website=user.site)