Updating Data

Saving changes to existing data

Editing a message

To demonstrate editing an existing item
in the database we can edit a message.

Create a template for editing a message

<form action="edit-message" method="post">

    <label>Message</label>
    <input name="message" type="text">

    <input type="submit" value="Save">

</form>

Write a new template called edit-message.html
which contains a form for editable fields.

Include a hidden field for the id

<form action="edit-message" method="post">

    <label>Message</label>
    <input name="message" type="text">

    <input name="message_id" type="hidden">

    <input type="submit" value="Save">

</form>

This will help us know which table row
to update when the form is submitted.

Route for editing a message

# edit message page
@website.route('/edit-message')
@usermanager.login_required
def edit_message():
    return render_template('edit-message.html')

Create a new route for the message editor
and display the correct template for it.

Set up the GET and POST methods

# edit message page
@website.route('/edit-message', methods=['GET', 'POST'])
@usermanager.login_required
def edit_message():

    if request.method == 'GET':
        return render_template('edit-message.html')

    elif request.method == 'POST':
        return redirect('/')

Pass the message id to the edit-message route

# edit message page
@website.route('/edit-message/<message_id>', methods=['GET', 'POST'])
@usermanager.login_required
def edit_message(message_id):

    if request.method == 'GET':
        return render_template('edit-message.html')

    elif request.method == 'POST':
        return redirect('/')

Load the message data in the route

if request.method == 'GET':

    query_string = (
        'SELECT message_id, content, user_id '
        'FROM messages '
        'WHERE message_id = ?'
    )

    query_result = datamanager.query_db(
        query_string, 
        [message_id],
        one=True
    )

    return render_template('edit-message.html')

Pass the message data to the template

return render_template('edit-message.html', message=query_result)

Pass the query result to the template
under the variable name message.

Display the message data in the form

<form action="edit-message" method="post">

    <label>Message</label>
    <input name="message" type="text" value="{{ message.content }}">

    <input name="message_id" type="hidden" value="{{ message.message_id }}">

    <input type="submit" value="Save">

</form>

Check that the form data shows up

localhost:5000/edit-message/1

Browse to the edit-message url in your
browser and check that the message is showing.

Saving the modified form data

The user can now make changes to the form
but the changes also need to be saved.

Make the message id optional so we can post

# edit message page
@website.route('/edit-message/<message_id>', methods=['GET', 'POST'])
@usermanager.login_required
def edit_message(message_id = None):

    ...

Write the POST processing

if request.method == 'POST':

    message_content = request.form.get('message')
    message_id = request.form.get('message_id')

    query_string = (
        'UPDATE messages '
        'SET content = ? '
        'WHERE message_id = ?'
    )

    query_result = datamanager.query_db(
        query_string, 
        [message_content, message_id],
        one=True
    )

    return redirect('/')

Check that it works

Edit a message in the browser
and check that it saves correctly.

Linking to an edit page

We can add a link to messages
that the user can click to edit.

Retrieve the message id for home page messages

@website.route('/')
def index():

    query_string = (
      'SELECT message_id, content, username, time_created ' 
      'FROM messages INNER JOIN users '
      'USING (user_id) '
      'ORDER BY time_created DESC'
    )

Update the query to load the message_id
so we can use it for our edit link.

{% for message in messages %}
    <li>
        {{ message['username'] }}: {{ message['content'] }}
        <a href="{{ url_for('edit_message', message_id = message['message_id']) }}">Edit</a>
    </li>
{% endfor %}

Modify the index.html template to
include an edit link on the message.

{% for message in messages %}
    <li>
        {{ message['username'] }}: {{ message['content'] }}
        {% if current_user.username == message['username'] %}
        <a href="{{ url_for('edit_message', message_id = message['message_id']) }}">Edit</a>
        {% endif %}
    </li>
{% endfor %}

Users should only be able to edit their
own messages, not messages by other people!

Thumbs Up!

Updating Data: Complete!

Take me to the next chapter!

Loading...