Create a template to handle the update. You can quickly do this by making a copy of the add template and
renaming it to update, as the forms will be similar. The main change will be updating
action="{{ url_for('add_category') }}
to
action="{{ url_for('edit_category') }}
.
Although this technically isn't necessary, as if the action attribute was not added, it would default to
submitting the form to the same route that rendered the page, which in this case would be edit_category.
Update Records
Create Template
Set up Route
Create a new route for edit_category in routes.py, concentrating on just the GET action, the default action that renders the page, for now.
@app.route("/edit_category", methods = [“GET”, “POST”])
def edit_category():
return render_template("edit_category.html")
Create Link
Create a link in the page for categories (categories.html) that will lead to the edit_category route. Make the href of the anchor tag:
{{ url_for('edit_category', category_id = category.id) }}
This can go inside a for loop that shows all the categories using the temporary variable of category. It takes
an extra argument of
category_id = category.id to pass the information to the route of the id of
the category.
category_id is the variable that we can access in the route, whereas
category.id is the dot notation getting the id value of the temporary category
variable from the for loop.
Update Route
Now we are passing a variable of
category_id
when we click the link, we can update our route to handle this variable being passed. First update the URL that
the route passes to so that there is a different page for each instance of the Model. We use
int: to tell the type of the data (in this case integer for the ID number)
and wrap the whole value in angular brackets.
@app.route ("/edit_category/<int:category_id>")
Now when we click on the link for the category with id of 1, we will be directed to the page of https://www.websitename.com/edit_category/1 and if we click of th elink for the category with an id of 2 we will be directed to the page of https://www.websitename.com/edit_category/2.
Then we need to pass this
category_id
variable that we defined in our href of the anchor tag to the function handling the route:
def edit_category(category_id)
Finally we can get the correct cateogry in our function by querying the Category table using that id. We use get_or_404 here so that the user is directed to the 404 page if they go to page that does not exist instead of creating an error. Then we pass that in our render_template function so that we can access that particular category on the edit_category page.
category = Category.query.get_or_404(category_id)
return render_template('edit_category.html', category = category)
Update Template
Now our route passes all the information to render the page, we can update edit_category.html.
Start with the action of the form to include the category id. Remember we passed the variable category in our render_template() function, so to access the id we can use dot notation of category.id.
{{ url_for('edit_category', category_id=category.id) }}
Then update the values of the input fields accordingly in order to pre-fill the form with the current values.
value = "{{ category.category_name }}"
Now we just need to handle the POST action of the form in our route in order to updat the records. Similar to the add POST action, we can get the value from the form, overwrite our current value and commit the changes before redirecting the user.
if request.method == "POST":
# Overwrite the current value with the one from the form
category.category_name = request.form.get("category_name")
# Save the change
db.session.commit()
# Redirect the user
return redirect(url_for("categories"))