Python flask - redirect to same page with query results

Viewed 1228

I've gone through a number of other answers, but can't work out how they relate to my issue. I'm relatively new to Python and Flask, but keen to learn.

Context is that I'm adding a father and / or mother on my home page (in any order) and redirecting to the /family/ page. Once I have that page displayed, I can add the other parent and then proceed to add the children. I can add as many children as I need, and every time I add a child's name, I want it to display in a list, with a blank pair of fields and an add button appearing after I add each child (ready for the next child). Most of this works fine BUT I'm trying to protect against the last child forename / surname I submitted being resubmitted when I refresh the page.

Here's part of my Python code:

@app.route("/family/<parentsid>", methods=["GET", "POST"])
def show_family(parentsid):

    form = AddIndividual()

    if request.method == "POST":

        if request.form.get("addfather") == "Add":
            add_father(form)

            return redirect(url_for("show_family", parentsid=session["partners.id"]))

        if request.form.get("addmother") == "Add":
            add_mother(form)

            return redirect(url_for("show_family", parentsid=session["partners.id"]))

        if request.form.get("addchild") == "Add":
            child_forenames = form.child_forenames.data
            child_surname = form.child_surname.data
            child_fullname = fullname(child_forenames, child_surname)

            new_child = Individual(child_surname, child_fullname, child_forenames)
            db.session.add(new_child)

            db.session.commit()
            db.session.flush()

            session["child.id"] = new_child.id

            link_child(individual_id=session["child.id"], parents_id=session["partners.id"])

            childlist = db.session.query(Individual.fullname).join(FamilyLink).filter(Parents.id == parentsid).all()
            children = [c[0] for c in childlist]

            session["children"] = children

            form.child_forenames.data = ""

            return render_template("home.html", form=form, father_fullname=father_fullname,
                                   mother_fullname=mother_fullname, children=children) # This is probably the problem!

            # return redirect(url_for("show_family", parentsid=session["partners.id"]))  This is the other line I've tried (see below)

    return render_template("home.html", form=form, father_fullname=father_fullname, mother_fullname=mother_fullname)

The relevant part of the HTML template is:

            <form method="POST" class="col-md-12">
                {{form.hidden_tag()}}
                    <div class="row">
                        <div class="col col-sm-6">
                            <h4>Children</h4>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col col-sm-6">
                            {% if children %}
                            <ul class="list-group">
                                {% for child in children %}
                                <li class="list-group-item"><h3>{{ child }}</h3></li>
                                {% endfor %}
                            </ul>
                            <br>
                            {% endif %}
                            <div class="input-group">
                                {{ form.child_forenames() }}
                                {{ form.child_surname() }}
                                <input type="submit" class="btn btn-primary" value="Add" name="addchild"/>
                            </div>
                        </div>
                    </div>
            </form>

From other answers, I'm sure the answer is to use redirect rather than render_template and potentially something around using GET (as well as the POST I need to submit the data from the form).

If I use return redirect(url_for("show_family", parentsid=session["partners.id"])) instead of render_template , the form doesn't resubmit anything which is great, but it doesn't show the children list at all (even though it saves the data fine).

Can anyone help please?

Thank you.

1 Answers

Redirect does a get on the page. It uses the render_template in the last line of our function. You do not pass the children there, so the page will not show them.

Related