Предварительно заполнить WTforms в колбе, с данными из объекта SQLAlchemy
Я новичок в флеш-фреймворке и создаю страницу профиля редактирования для вебпортала. Я застрял в точке и не могу автозаполнять форму.
Вот мой класс формы:
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 %}
У меня есть объект класса пользователя. И из этого объекта я хочу заранее заполнить эту форму. Как я могу преобставить значения в форме. Я пытаюсь реализовать функцию редактирования профиля здесь.
Ответы
Ответ 1
Вам нужно передать свой объект в форму при ее создании.
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()
.
Ответ 2
Самый простой способ, который я нашел, - заполнить поля формы в запросе на получение.
@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
. Ответ Dirn предлагает несколько правильных действий.
Ответ 3
Чтобы заполнить форму с помощью объекта SQLAlchemy, выполните следующие действия:
form = EditProfile(obj=<SQLAlchemy_object>)
Если поля формы не совпадают с столбцами базы данных в вашей модели по какой-либо причине (они должны), класс формы принимает kwargs:
** kwargs - Если ни formdata, ни obj не содержит значения для поля, форма присваивает значение соответствующего аргумента ключевого слова поле, если оно предусмотрено.
Я обнаружил, что для этого используется один случай использования, если у вас есть форма, содержащая поля, которые ссылаются на несколько моделей (например, через отношения); пропускать один obj
недостаточно.
Итак, рассмотрим ваш пример и скажем, что в вашей модели базы данных (для user
) вместо website
(имя поля формы) используется site
. Вы сделаете это, чтобы заполнить свою форму из объекта SQLAlchemy:
form = EditProfile(obj=user, website=user.site)
Затем в POST вам нужно будет сделать это, чтобы заполнить ваш объект SQLAchemy из вашей формы:
form.populate_obj(user)
user.site = form.website.data
db.session.commit()