Python 使用来自 SQLAlchemy 对象的数据在烧瓶中预填充 WTforms

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23712986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:22:05  来源:igfitidea点击:

Pre-Populate a WTforms in flask, with data from a SQLAlchemy object

pythonflaskflask-sqlalchemyflask-wtforms

提问by Hammad Haleem

I am fairly new to flask framework and was creating an edit profile page for a webportal. I am stuck at a point and am unable to autofill a form.

我对 Flask 框架相当陌生,正在为门户网站创建编辑配置文件页面。我被困在某个点上,无法自动填写表格。

Here is my form class :

这是我的表单类:

class EditProfile(Form):

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

This is my function that evaluates the form.

这是我评估表单的函数。

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"

And my html template for form is form is :

我的表单 html 模板是 form 是:

{% 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 %}



I have an object, of user class. And from that object I want to prefill this form.How can I prepopulate the values in the form. I am trying to implement the edit profile functionality here.

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

采纳答案by dirn

You need to pass your object to the form when you create it.

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

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

You're going to run into some trouble with

你会遇到一些麻烦

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

It creates a new instance of your EditProfileform. You then try to add it to the session. The session wants models, not forms.

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

Instead, after validating the form, you can associate its values with the object.

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

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

Because your object was already loaded, you won't need to add it to the session. You can remove db.session.add(query)and just call db.session.commit().

因为您的对象已经加载,所以您不需要将它添加到会话中。您可以删除db.session.add(query)并调用db.session.commit().

回答by Eric Workman

The easiest way I've found of doing this is to fill the form fields on a get request.

我发现这样做的最简单方法是在 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")

This sets up the function to return a prefilled form on a get request. You'll have to rework the section under form.validate_on_submit. Dirn's answer suggests a few of the right things to do.

这将设置函数以在获取请求时返回预填充的表单。您必须重新编写 下的部分form.validate_on_submit。Dirn 的回答提出了一些正确的做法。

回答by brenj

To populate the form with your SQLAlchemy object use:

要使用 SQLAlchemy 对象填充表单,请使用:

form = EditProfile(obj=<SQLAlchemy_object>)

If your form fields don't match the database columns in your model for whatever reason (they should), the form class takes kwargs:

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

**kwargs – If neither formdata or obj contains a value for a field, the form will assign the value of a matching keyword argument to the field, if provided.

**kwargs – 如果 formdata 或 obj 都不包含字段的值,则表单将为该字段分配匹配关键字参数的值(如果提供)。

I found that one use case for this is if you have a form that contains fields that reference more than one model (e.g. through a relationship); passing the one objisn't enough.

我发现一个用例是,如果您的表单包含引用多个模型的字段(例如,通过关系);通过一个obj是不够的。

So let's take your example and say that in your database model (for user) you use siteinstead of website(the form field name). You'd do this to populate your form from the SQLAlchemy object:

因此,让我们以您的示例为例,说在您的数据库模型 (for user) 中您使用site而不是website(表单字段名称)。您可以这样做以从 SQLAlchemy 对象填充您的表单:

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

Then in the POST you'd have to do this to populate your SQLAchemy object from your form:

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

form.populate_obj(user)
user.site = form.website.data
db.session.commit()