2014-05-17 12 views
13

Tôi là khá mới vào khung bình và đã tạo một trang hồ sơ chỉnh sửa cho một webportal. Tôi bị kẹt tại một điểm và không thể tự động điền một biểu mẫu.Pre-Populate một WTforms trong bình, với dữ liệu từ một đối tượng SQLAlchemy

Đây là lớp mẫu của tôi:

class EditProfile(Form): 

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

Đây là chức năng của tôi mà đánh giá biểu mẫu.

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" 

Và template html của tôi cho hình thức là hình thức là:

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


tôi có một đối tượng, về thành viên lớp. Và từ đối tượng đó tôi muốn điền vào biểu mẫu này. Làm cách nào tôi có thể chuẩn bị trước các giá trị trong biểu mẫu. Tôi đang cố triển khai chức năng chỉnh sửa hồ sơ ở đây.

Trả lời

14

Bạn cần chuyển đối tượng của mình vào biểu mẫu khi tạo.

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

Bạn sẽ gặp phải một số rắc rối với

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

Nó tạo ra một thể hiện mới của hình thức EditProfile của bạn. Sau đó, bạn thử thêm nó vào phiên. Phiên này muốn các mô hình, chứ không phải biểu mẫu.

Thay vào đó, sau khi xác thực biểu mẫu, bạn có thể kết hợp các giá trị của nó với đối tượng.

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

Vì đối tượng của bạn đã được tải, bạn sẽ không cần phải thêm đối tượng đó vào phiên. Bạn có thể xóa db.session.add(query) và chỉ cần gọi db.session.commit().

+0

tôi vẫn một chút bối rối. Một khi tôi đang gửi đối tượng người dùng của tôi trong các hình thức tôi cần phải chỉnh sửa các mẫu tôi cũng nghĩ, nếu không thì làm thế nào nó sẽ kết hợp đúng feild chính xác với các mô hình? Vì các thành viên dữ liệu trong mô hình người dùng và lớp biểu mẫu của tôi có các tên khác nhau. –

+0

Tại sao chúng khác nhau? Ngoài ra, bạn có thể cho chúng tôi thấy mô hình không? – dirn

+0

https://github.com/hammadhaleem/fedora-college/blob/develop/fedora_college/core/models.py Đây là các mô hình của tôi. –

5

Cách dễ nhất tôi đã tìm được khi thực hiện việc này là điền vào các trường biểu mẫu trên yêu cầu nhận.

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

này thiết lập các chức năng để trả lại một hình thức đóng sẵn trên một yêu cầu get. Bạn sẽ phải làm lại phần dưới form.validate_on_submit. Câu trả lời của Dirn gợi ý một vài điều đúng đắn cần làm.

4

Để cư dưới hình thức với việc bạn sử dụng đối tượng SQLAlchemy:

form = EditProfile(obj=<SQLAlchemy_object>) 

Nếu lĩnh vực hình thức của bạn không phù hợp với các cột cơ sở dữ liệu trong mô hình của bạn vì lý do gì (họ cần), các lớp mẫu mất kwargs:

** kwargs - Nếu không phải formdata hoặc obj chứa giá trị cho trường, biểu mẫu sẽ chỉ định giá trị của đối số từ khóa phù hợp cho trường , nếu được cung cấp.

Tôi thấy rằng một trường hợp sử dụng cho điều này là nếu bạn có biểu mẫu chứa các trường tham chiếu nhiều hơn một mô hình (ví dụ: thông qua mối quan hệ); chuyển số obj là không đủ.

Vì vậy, hãy lấy ví dụ của bạn và nói rằng trong mô hình cơ sở dữ liệu của bạn (cho user) bạn sử dụng site thay vì website (tên trường biểu mẫu). Bạn muốn làm điều này để cư mẫu của bạn từ đối tượng SQLAlchemy:

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

Sau đó, trong quá trình POST bạn phải làm điều này để cư đối tượng SQLAchemy của bạn từ hình thức của bạn:

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

làm cách nào tôi có thể phục hồi lại MultiSelectField? tôi không có ý định sử dụng obj, tôi muốn sử dụng tên trường nhưng nó không hoạt động đối với tôi –

Các vấn đề liên quan