2016-01-08 2 views
1

У меня есть пользователь с местоположением. Точно так же, как доказательство концепции, Location является FormField в CombinedForm, который должен храниться как модель пользователя. В конце концов, я хочу иметь довольно большое количество вложенных форм, поэтому мне бы очень хотелось, чтобы form.populate_obj (Model) заботился о обработке данных. Однако я должен делать что-то неправильно. Вот мой код:Как использовать populate_obj в Flask/WTForms с FormField?

# - - - Models - - - 
class User(db.Model): 
    __tablename__ = 'users' 
    id = db.Column(db.Integer(), primary_key=True) 
    username = db.Column(db.String(40)) 
    location = db.relationship('Location', backref='user') 

class Location(db.Model): 
    __tablename__ = 'locations' 
    id = db.Column(db.Integer(), primary_key=True) 
    user_id = db.Column(db.Integer(), db.ForeignKey('users.id')) 
    descr = db.Column(db.String(50)) 

# - - - Forms - - - 
class LocationForm(NoCsrfForm): 
    descr = StringField('Location Name') 

class CombinedForm(Form): 
    username = StringField('User', validators=[DataRequired()]) 
    location = FormField(LocationForm) # , default=lambda: Location()) 
    submit = SubmitField('Submit') 

# - - - Routes - - - 
@app.route('/', methods=['GET', 'POST']) 
def index(): 
    user = User(username="not in db") 
    form = CombinedForm(obj=user) 
    if form.validate_on_submit(): 
     form.populate_obj(user) 
     db.session.add(user) 
     db.session.commit() 
    return render_template('multi.html', form=form) 

Когда я добавляю user.location = [Location(descr="Test")] к индексной функции я могу оказать поле с помощью {{ form.location }} на мой взгляд, но изменения поля в форме не влияет на модели, так как populate_obj не заполняет объект Location данными POST. Когда FormField находится внутри FieldList, его заполнение заполняется.

Что мне не хватает?

Мне не удалось найти рабочий пример FormField без FieldList.

Я потратил много времени на это, даже сделал example, когда я думал, что понял, но я ошибся, по крайней мере, при использовании FormField с populate_list без FieldList. Если есть лучший подход к обработке данных из 2-3 моделей в одной форме, пожалуйста, дайте мне знать. Я схожу с ума, поэтому я бы очень признателен за помощь. Спасибо за ваше время.

ответ

0

Кажется, что я действительно запутался в голове и получил неправильные отношения. Приведен пример ниже.

Обратите внимание, что если вы передадите объект, как экземпляр пользователя, в форму, у него уже есть место заселения. Если вы передадите пользователя без местоположения, populate_obj не сможет найти новое местоположение из формы при отправке.

Есть ли способ обойти это?

Это должно работать как поле формы доказательство концепции:

# - - - Models - - - 
class User(db.Model): 
    __tablename__ = 'users' 
    id = db.Column(db.Integer(), primary_key=True) 
    username = db.Column(db.String(40)) 
    location_id = db.Column(db.Integer, db.ForeignKey('locations.id')) 


class Location(db.Model): 
    __tablename__ = 'locations' 
    id = db.Column(db.Integer(), primary_key=True) 
    descr = db.Column(db.String(50)) 
    users = db.relationship('User', backref='location') 


# - - - Forms - - - 
class LocationForm(NoCsrfForm): 
    descr = StringField('Location Name') 


class CombinedForm(Form): 
    username = StringField('User', validators=[DataRequired()]) 
    location = FormField(LocationForm, default=lambda: Location()) 
    submit = SubmitField('Submit') 


# - - - Routes - - - 
@app.route('/', methods=['GET', 'POST']) 
def index(): 
    user = User(username="Def") 
    form = CombinedForm() # don't put a user obj in unless it has a location! 
    if form.validate_on_submit(): 
     form.populate_obj(user) 
     db.session.add(user) 
     db.session.commit() 
    return render_template('multi.html', form=form)