提交 Flask WTForms 时,如何将字段留空而不从数据库中删除这些值 table?
When submitting a Flask WTForms, how can fields be left blank without blanking-out those values from the database table?
问题:
我正在开发一个带有 WTForms EditProfileForm 的 Flask 应用程序,其中包含:名字、姓氏、用户名,和关于我。表单加载 Username 和 About Me 自动填充。 名字和姓氏为空。如果用户编辑关于我的 TextAreaField,但将 First Name 和 Last Name 字段留空,则提交表单会将这些 DB 字段改写为空白。
相关代码示例:
在下面的 forms.py 代码示例中,我在 firstname
和 lastname
上设置了 validators=[DataRequired()])
,但由于这些字段显示为空白,因此需要用户在他们想要编辑任何字段时重新输入他们的名字和姓氏。所以我删除了那些验证器。
还有一个关于名字和姓氏的用户名验证功能,因此如果用户不更改他们的用户名(必须是唯一的),则在提交时查询不会 return用户名必须是唯一的误报错误。
forms.py - EditProfileForm class:
class EditProfileForm(FlaskForm):
firstname = StringField('First Name')
lastname = StringField('Last Name')
username = StringField('Username', validators=[DataRequired()])
about_me = TextAreaField('About Me', validators=[Length(min=0, max=140)])
submit = SubmitField('Submit')
def __init__(self, original_username, *args, **kwargs):
super(EditProfileForm, self).__init__(*args, **kwargs)
self.original_username = original_username
def validate_username(self, username):
if username.data != self.original_username:
user = User.query.filter_by(username=self.username.data).first()
if user is not None:
raise ValidationError('Please choose a different username.')
- 我在视图函数中找不到导致
firstname
和 lastname
字段显示为空白但 username
和 about_me
字段自动显示的任何内容-填充。
routes.py - edit_profile 视图
@app.route('/edit_profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
form = EditProfileForm(current_user.username)
if form.validate_on_submit():
current_user.firstname = form.firstname.data
current_user.lastname = form.lastname.data
current_user.username = form.username.data
current_user.about_me = form.about_me.data
db.session.commit()
flash(_('Your changes have been saved.'))
return redirect(url_for('edit_profile'))
elif request.method == 'GET':
form.username.data = current_user.firstname
form.username.data = current_user.lastname
form.username.data = current_user.username
form.about_me.data = current_user.about_me
return render_template('edit_profile.html', title=_('Edit Profile'),
form=form)
models.py - 用户 class
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(50), index=True)
lastname = db.Column(db.String(50), index=True)
username = db.Column(db.String(50), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
about_me = db.Column(db.String(140))
def __repr__(self):
return '<User {}>'.format(self.username)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
edit_profile.html
{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<h1>Edit Profile</h1>
<div class="row">
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
</div>
{% endblock %}
只需插入简单的 if
逻辑即可。
if form.firstname.data:
current_user.firstname = form.firstname.data
if form.lastname.data:
current_user.lastname = form.lastname.data
如果用户无法 edit/change username
为什么要将其创建为可编辑字段?最好将其作为隐藏字段并传递数据。
在我看来,您的表格不一致。为什么自动填充某些字段而不是其他字段?
如果用户是新用户并且您是第一次收集数据,那么所有字段都应为空白且可编辑。
如果表单要编辑详细信息,那么所有字段都应该自动填充,用户名应该隐藏,因为你说他不能更改。
事实证明,问题是我在 routes.py edit_profile 视图函数中犯的一个简单的 copy/paste 错误。我有这个...
form.username.data = current_user.firstname
form.username.data = current_user.lastname
form.username.data = current_user.username
form.about_me.data = current_user.about_me
我在四个字段中的三个字段中获得 form.username.data
。呸!
问题:
我正在开发一个带有 WTForms EditProfileForm 的 Flask 应用程序,其中包含:名字、姓氏、用户名,和关于我。表单加载 Username 和 About Me 自动填充。 名字和姓氏为空。如果用户编辑关于我的 TextAreaField,但将 First Name 和 Last Name 字段留空,则提交表单会将这些 DB 字段改写为空白。
相关代码示例:
在下面的 forms.py 代码示例中,我在
firstname
和lastname
上设置了validators=[DataRequired()])
,但由于这些字段显示为空白,因此需要用户在他们想要编辑任何字段时重新输入他们的名字和姓氏。所以我删除了那些验证器。还有一个关于名字和姓氏的用户名验证功能,因此如果用户不更改他们的用户名(必须是唯一的),则在提交时查询不会 return用户名必须是唯一的误报错误。
forms.py - EditProfileForm class:
class EditProfileForm(FlaskForm):
firstname = StringField('First Name')
lastname = StringField('Last Name')
username = StringField('Username', validators=[DataRequired()])
about_me = TextAreaField('About Me', validators=[Length(min=0, max=140)])
submit = SubmitField('Submit')
def __init__(self, original_username, *args, **kwargs):
super(EditProfileForm, self).__init__(*args, **kwargs)
self.original_username = original_username
def validate_username(self, username):
if username.data != self.original_username:
user = User.query.filter_by(username=self.username.data).first()
if user is not None:
raise ValidationError('Please choose a different username.')
- 我在视图函数中找不到导致
firstname
和lastname
字段显示为空白但username
和about_me
字段自动显示的任何内容-填充。
routes.py - edit_profile 视图
@app.route('/edit_profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
form = EditProfileForm(current_user.username)
if form.validate_on_submit():
current_user.firstname = form.firstname.data
current_user.lastname = form.lastname.data
current_user.username = form.username.data
current_user.about_me = form.about_me.data
db.session.commit()
flash(_('Your changes have been saved.'))
return redirect(url_for('edit_profile'))
elif request.method == 'GET':
form.username.data = current_user.firstname
form.username.data = current_user.lastname
form.username.data = current_user.username
form.about_me.data = current_user.about_me
return render_template('edit_profile.html', title=_('Edit Profile'),
form=form)
models.py - 用户 class
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(50), index=True)
lastname = db.Column(db.String(50), index=True)
username = db.Column(db.String(50), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
about_me = db.Column(db.String(140))
def __repr__(self):
return '<User {}>'.format(self.username)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
edit_profile.html
{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<h1>Edit Profile</h1>
<div class="row">
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
</div>
{% endblock %}
只需插入简单的 if
逻辑即可。
if form.firstname.data:
current_user.firstname = form.firstname.data
if form.lastname.data:
current_user.lastname = form.lastname.data
如果用户无法 edit/change username
为什么要将其创建为可编辑字段?最好将其作为隐藏字段并传递数据。
在我看来,您的表格不一致。为什么自动填充某些字段而不是其他字段?
如果用户是新用户并且您是第一次收集数据,那么所有字段都应为空白且可编辑。
如果表单要编辑详细信息,那么所有字段都应该自动填充,用户名应该隐藏,因为你说他不能更改。
事实证明,问题是我在 routes.py edit_profile 视图函数中犯的一个简单的 copy/paste 错误。我有这个...
form.username.data = current_user.firstname
form.username.data = current_user.lastname
form.username.data = current_user.username
form.about_me.data = current_user.about_me
我在四个字段中的三个字段中获得 form.username.data
。呸!