Skip to content

Profile Update Form Submission

Manish Sah edited this page Oct 3, 2020 · 1 revision

Now that we have profile update form, route and page, we need to display the form so that user can modify their profile.

As a starting point, lets copy the contents inside and including from tag in registration.html and paste them in our profile.html just above the ---FORM HERE --- comment.

<form method="POST" action="" enctype="multipart/form-data">
        {{ form.hidden_tag() }}
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Profile Information</legend>
            <div class="form-group">

                {{ form.username.label(class="form-control-label") }}
                {% if form.username.errors %}
                {{ form.username(class="form-control form-control-lg is-invalid") }}
                <div class="invalid-feedback">
                    {% for error in form.username.errors %}
                    <span>{{ error }}</span>
                    {% endfor %}
                </div>
                {% else %}
                {{ form.username(class="form-control form-control-lg") }}
                {% endif %}
            </div>
            <div class="form-group">
                {{ form.email.label(class="form-control-label") }}
                {% if form.email.errors %}
                {{ form.email(class="form-control form-control-lg is-invalid") }}
                <div class="invalid-feedback">
                    {% for error in form.email.errors %}
                    <span>{{ error }}</span>
                    {% endfor %}
                </div>
                {% else %}
                {{ form.email(class="form-control form-control-lg") }}
                {% endif %}
            </div>
            <div class="form-group">
                {{ form.picture.label() }}
                {{ form.picture(class="form-control-file") }}
                {% if form.picture.errors %}
                    {% for error in form.picture.errors %}
                    <span class="text-danger">{{ error }}</span><br>
                    {% endfor %}
                {% endif %}
            </div>



        </fieldset>
        <div class="form-group">
            {{ form.submit(class="btn btn-outline-info") }}
        </div>

    </form>

we will keep the form fields username,email and delete the password field. We will add new field for profile image.

Also, we will add new attribute, enctype="multipart/form-data", in opening form tag.

our profile.html will now look like this

{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
  <div class="media">
    <img class="rounded-circle account-img" src="/static/profile_pictures/default.jpg">
    <div class="media-body">
      <h2 class="account-heading">{{ current_user.username }}</h2>
      <p class="text-secondary">{{ current_user.email }}</p>
    </div>
  </div>
  <!-- FORM HERE -->
    <form method="POST" action="" enctype="multipart/form-data">
        {{ form.hidden_tag() }}
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Profile Information</legend>
            <div class="form-group">

                {{ form.username.label(class="form-control-label") }}
                {% if form.username.errors %}
                {{ form.username(class="form-control form-control-lg is-invalid") }}
                <div class="invalid-feedback">
                    {% for error in form.username.errors %}
                    <span>{{ error }}</span>
                    {% endfor %}
                </div>
                {% else %}
                {{ form.username(class="form-control form-control-lg") }}
                {% endif %}
            </div>
            <div class="form-group">
                {{ form.email.label(class="form-control-label") }}
                {% if form.email.errors %}
                {{ form.email(class="form-control form-control-lg is-invalid") }}
                <div class="invalid-feedback">
                    {% for error in form.email.errors %}
                    <span>{{ error }}</span>
                    {% endfor %}
                </div>
                {% else %}
                {{ form.email(class="form-control form-control-lg") }}
                {% endif %}
            </div>
            <div class="form-group">
                {{ form.picture.label() }}
                {{ form.picture(class="form-control-file") }}
                {% if form.picture.errors %}
                    {% for error in form.picture.errors %}
                    <span class="text-danger">{{ error }}</span><br>
                    {% endfor %}
                {% endif %}
            </div>



        </fieldset>
        <div class="form-group">
            {{ form.submit(class="btn btn-outline-info") }}
        </div>

    </form>
</div>
{% endblock content %}

Now we need to implement the logic when user submits the form. lets update our profile route as follows:

.
import os
.

@app.route("/profile", methods=["GET", "POST"])
@login_required
def profile():
    form = ProfileUpdateForm()
    if form.validate_on_submit():
        current_user.username = form.username.data
        current_user.email = form.email.data
        if form.picture.data:
            # extract filename and extension from image uploaded by user
            filename, file_extension = os.path.splitext(form.picture.data.filename)

            # create new name for the image uploaded by user, as the multiple user can upload the image with same name
            new_file_name = current_user.username + file_extension

            # generate path for the saving the image
            file_path = os.path.join(app.root_path, 'static/profile_pictures', new_file_name)

            # save the image in that locoation
            form.picture.data.save(file_path)

            # save the name of file in our database
            current_user.image_file = new_file_name
        db.session.commit()
        flash('Your profile was updated', 'success')
        return redirect("/profile")
    form.username.data = current_user.username
    form.email.data = current_user.email
    return render_template('profile.html', title_name='profile', form=form)
  • Note: we need to change the src in img tag in our profile page so that current profile image is displayed
<img class="rounded-circle account-img" src="/static/profile_pictures/{{ current_user.image_file }}">

Implementation can be found over this commit

Clone this wiki locally