Ответ 1
Я также сталкивался с чем-то подобным ранее. Я попытался решить эту проблему с помощью model_form, но это не совсем решает проблему динамического добавления новых записей, и мне было трудно использовать ее при работе с отношениями.
Использование QuerySelectField в WTForms поможет вам заполнить, например. < выберите > с идентификаторами, парами значений, соответствующими существующим адресам. Но он по-прежнему отображает регулярную форму html в шаблоне.
Используя какой-то мультиселектор с возможностью динамически добавлять новые параметры в интерфейсе, вы можете отправлять дополнительные адреса в той же форме. Конечная точка будет заботиться о создании новых адресов, если они не существуют в db.
Форма WTForm будет:
from app import db
class PersonAddressForm(Form):
id = HiddenField('id')
name = StringField('Name')
addresses = QuerySelectField('Addresses',
query_factory=lambda: db.session.query(Address),
get_pk=lambda a: a.id, get_label=lambda a: a.name)
# Custom validate
def validate(self):
# ... custom validation
return True
И маршрут вроде как:
# ... this will be used to create and update a user
@route('create/<userid>', methods=["GET"])
def get_user_form(userid):
# ... Get the Person
user = Person()
if userid:
# ... if userid supplied, use existing Person object
user = Person.query.get(userid)
# ... Populate the form
person_form = PersonAddressForm(obj=user)
# ... return form
return render_template('somepage.html', form=person_form)
@route('create/<userid>', methods=["POST"])
def post_person_form(userid):
person_form = PersonAddressForm(request.form)
if person_form.validate():
# ... Get db object
person = db.session.query(Person).get(form.id)
# ... Add changes to the object from the form
person_form.populate_obj(obj=person_address)
# ... Get addresses
addresses = form.addresses.raw_data
# ... loop over and add to person
for address in addresses:
# Add or create an address
actual_address = db.session.query(Address).get(address.id)
# ... check if address is existing
if not actual_address:
# ... if address not existing, create new one
actual_address = Address(address.name)
db.session.add(actual_address)
# ... Append new or created address to person
person.addresses.append(actual_address)
# ... save changes to the db
db.session.commit()
# ... Update/Create complete
return redirect(url_for('get_users'))
else:
# ... form not valid, notify user
# ...
Это приведет к редактированию/созданию пользователя и созданию адреса. А также создайте связь между ними. Чтобы он также поддерживал удаление адреса, измените
person.addresses.append(actual_address)
к
person.addresses = list_of_actual_addresses
и измените это в модели человека (cascade = 'delete-orphan')
addresses = db.relationship('Address', secondary=personaddress, cascade='delete-orphan' backref=db.backref('person', lazy='dynamic'))
Это приведет к тому, что форма обновит все отношения адресов каждый раз, и каскад удалит осиротевшие адреса. Таким образом, весь список адресов для человека будет обновляться каждый раз при отправке формы.
При работе с WTForms в шаблонах я настоятельно рекомендую использовать макросы, если вы этого еще не сделали. Вам придется переписать его в некоторой степени, но проверьте этот вне.
Надеюсь, что это поможет