Как при отправке Flask WTForms полей можно оставить пустыми, не исключая эти значения из таблицы базы данных? - PullRequest
1 голос
/ 07 февраля 2020

Вопрос:

Я работаю над приложением Flask с WTForms EditProfileForm, содержащим: Имя , Фамилия , Имя пользователя и О себе . Форма загружается с Имя пользователя и Обо мне автоматически заполняется. Имя и Фамилия не заполнены. Если пользователь редактирует поле «Обо мне» TextAreaField, но оставляет поля «Имя» и «Фамилия» пустыми, то при отправке формы эти поля БД перезаписываются как пустые.

Примеры связанных кодов:

  • В следующем примере кода forms.py у меня было validators=[DataRequired()]) на firstname и lastname , но так как эти поля показывались пустыми, пользователю требовалось повторно вводить свое имя и фамилию в любое время, когда они хотели редактировать любые поля. Поэтому я удалил эти валидаторы.

  • Также по имени и фамилии есть функция проверки имени пользователя, так что если пользователь не меняет свое имя пользователя, которое должно быть уникальным, при отправке запроса не возвращает ложноположительную ошибку о том, что имя пользователя должно быть уникальным.

forms.py - EditProfileForm класс:

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.')
  • Я не могу найти ничего в функция View, которая приводит к тому, что поля firstname и lastname отображаются пустыми, а поля username и about_me заполняются автоматически.

rout.py - edit_profile view

@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 %}

Ответы [ 2 ]

1 голос
/ 09 февраля 2020

Просто вставьте простые if logi c.

if form.firstname.data:
    current_user.firstname = form.firstname.data
if form.lastname.data:
    current_user.lastname = form.lastname.data

Если пользователь не может редактировать / изменять username, почему вы создаете это как редактируемое поле? Было бы лучше иметь это как скрытое поле и передавать данные.

Мне кажется, что ваша форма противоречива. Почему автоматическое заполнение одних полей, а не других?

Если пользователь новый и вы собираете данные впервые, все поля должны быть пустыми и редактируемыми.

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

0 голосов
/ 10 февраля 2020

Оказывается, проблема была в простой ошибке копирования / вставки, которую я допустил в функции представления rout.py edit_profile. У меня было это ...

    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 в трех из четырех полей. Doh!

...