提交 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 应用程序,其中包含:名字姓氏用户名,和关于我。表单加载 UsernameAbout Me 自动填充。 名字姓氏为空。如果用户编辑关于我的 TextAreaField,但将 First Name 和 Last Name 字段留空,则提交表单会将这些 DB 字段改写为空白。

相关代码示例:

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.')

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。呸!