web-dev-qa-db-ja.com

SQLAlchemyオブジェクトからのデータを使用して、フラスコ内のWTformに事前入力します。

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テンプレートはform is:

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


ユーザークラスのオブジェクトがあります。そして、そのオブジェクトからこのフォームに事前入力します。フォームに値を事前入力するにはどうすればよいですか。ここでプロファイル編集機能を実装しようとしています。

18
Hammad Haleem

作成時にオブジェクトをフォームに渡す必要があります。

_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()を呼び出すだけです。

21
dirn

これを行う最も簡単な方法は、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の下のセクションを書き直す必要があります。ディーンの答えは、正しいことのいくつかを示唆しています。

8
Eric Workman

SQLAlchemyオブジェクトをフォームに入力するには、以下を使用します。

form = EditProfile(obj=<SQLAlchemy_object>)

フォームフィールドが何らかの理由で(当然のことながら)モデルのデータベース列と一致しない場合、フォームクラスはkwargsを使用します。

** kwargs – formdataもobjもフィールドの値を含まない場合、フォームは、一致するキーワード引数の値をフィールドに割り当てます(指定されている場合)。

これの1つの使用例は、複数のモデルを参照するフィールドを含むフォームがある場合(たとえば、関係を介して)であることがわかりました。 objを渡すだけでは十分ではありません。

それでは、例を挙げて、データベースモデル(user)では、site(フォームフィールド名)の代わりにwebsiteを使用するとします。次のようにして、SQLAlchemyオブジェクトからフォームにデータを入力します。

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

次に、POSTで、フォームからSQLAchemyオブジェクトにデータを入力するためにこれを行う必要があります。

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