2014-05-17 49 views
13

我對燒瓶框架相當新,並且正在爲webportal創建編輯配置文件頁面。我被困在某一點,無法自動填寫表單。使用SQLAlchemy對象中的數據預填充燒瓶中的WTforms

這裏是我的表單類:

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


我有一個對象,用戶類的。從這個對象我想預先填寫這種形式。我可以如何預先填寫表單中的值。我正試圖在這裏實現編輯配置文件功能。

回答

14

創建它時,需要將對象傳遞給表單。

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()即可。

+0

我仍然有點困惑。一旦我發送我的用戶對象的形式,我需要編輯模板,我想,否則它將如何將正確的正確的領域與模型關聯?由於我的用戶模型和表單類中的數據成員具有不同的名稱。 –

+0

他們爲什麼不同?另外,你能告訴我們模型嗎? – dirn

+0

https://github.com/hammadhaleem/fedora-college/blob/develop/fedora_college/core/models.py 這是我的模特。 –

5

我發現這樣做的最簡單方法是在獲取請求上填寫表單域。

@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") 

這設置函數返回一個獲取請求的預填表單。您必須重新編寫form.validate_on_submit下的部分。德恩的回答暗示了一些正確的做法。

4

當您SQLAlchemy的對象使用填充表單:

form = EditProfile(obj=<SQLAlchemy_object>) 

如果你的表單字段不會在你的模型無論出於何種原因匹配數據庫列(他們應該),窗體類需要kwargs:

** kwargs - 如果formdata或obj都不包含字段值,則表單會將匹配關鍵字參數的值分配給 字段(如果提供)。

我發現一個用例就是如果你有一個包含引用多個模型的字段的表單(例如通過關係);通過一個obj是不夠的。

因此,讓我們以您的示例爲例,說您的數據庫模型(對於user),您使用site而不是website(表單字段名稱)。在POST

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

那麼你就必須做到這一點,從您的表單填充您的SQLAchemy對象:你可以這樣做,從SQLAlchemy的對象來填充表單

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

如何重新填充MultiSelectField?我不是說要使用obj,我想使用字段名稱,但它不適用於我 –