Different html page for POST and GET methods for the same app.route (Flask)

Question:

I am writing a program that randomizes a users lists of movies which is stored in a sql database. The code itself is unimportant for my question (I think) but I’ll still leave it just in case. As you see below, the same page is rendered in the get and post request. What I want to do is render a different template for the post and get request of the same route. So in the post request I would like to render a template the just displays a list of the randomized movies. I know how to do an html page for that, what I don’t know is how, or what is the best way, of having a different html pages for both methods YET maintain the same URL, the same route (/randomizer). Sorry if the question is confusing and thank you in advance!

Python Code from ‘app.py’:

@app.route("/randomizer", methods=["GET", "POST"])
def randomizer():

# GET request
if request.method == "GET":
    return render_template("randomizer.html", genres=userGenres(session['user_id'])
# POST request
else: 
    # Recieve and print data
    form_data = request.get_json()

    # Movie status from form
    status = form_data['status']

    # List of genres checked in form
    form_genres = form_data['genres']

    # Initialize list for movies that pass the genre tag
    mlist2 = []

    # Initialize a list for the final movies to be randomized
    final_movies = []

    # Get release year from data
    ry = form_data['year']

    # Turn blank inputs into
    lower = int(ry[0] or lower_limit)
    upper = int(ry[1] or upper_limit)


    " MOVIE STATUS "
    # Listdict of all movies with that status (without tags applied)
    if status == 'unseen':
        mlist1 = db.execute("SELECT * FROM movies WHERE status = ? AND user_id = ?", 0, session['user_id'])
    elif status == 'seen':
        mlist1 = db.execute("SELECT * FROM movies WHERE status = ? AND user_id = ?", 1, session['user_id'])
    else:
        mlist1 = db.execute("SELECT * FROM movies WHERE user_id = ?", session['user_id'])


    " GENRES "
    # If any genre was clicked, rather than 'All Genres', query for genres
    if form_genres[0] != 'All Genres':

        # Loop through movies
        for movie in mlist1:

            # Loop through genres
            for g in form_genres:

                # Check for genre in movie
                passed = db.execute("SELECT * FROM genres WHERE movie_id = ? AND genre = ?", movie['id'], g)

                # If passed is not blank (movie is from genre)
                if passed:

                    # Only add movie if it is not already in the list
                    if movie not in mlist2:

                        # Add movie to final list
                        mlist2.append(movie)

    # If all genres want to be randomized, the list will be the same
    else:
        mlist2 = mlist1


    " RELEASE YEAR "
    # Loop through movies only if a limit was given
    if not (lower == lower_limit and upper == upper_limit):
        # Loop through movies
        for m in mlist2:
            # Get release year of movie
            movie_year = db.execute("SELECT year FROM movies WHERE id = ?", m['id'])

            # Check
            if lower <= movie_year <= upper:
               final_movies.append(m)

    # Else the list will be the same as before
    else:
        final_movies = mlist2

    # Shuffle final list to finally randomize
    random.shuffle(final_movies)

    return render_template("randomizer.html", movies = final_movies)

HTML code from ‘randomizer.html’:

{% extends "layout.html" %}

{% block title %}
Randomizer
{% endblock %}

{% block main %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
    function genreChecked(element) {
        // Unclick genres if all-genres is clicked and vice versa
        var allGenres = document.getElementById('all-genres');
        var genres = document.getElementsByName('cbox-genre');

        // Check if all-genres clicked
        if (element.id == 'all-genres') {
            // Uncheck all other genres
            for (var i = 0; i < genres.length; i++) {
                genres[i].checked = false;
            }
        }

        // If any other genre is clicked, unclick all-genres
        else {
            allGenres.checked = false;
        }
    }

    function testing() {

        // All radio
        let radios = document.getElementsByName('radio-seen');
        for (var i = 0; i < radios.length; i++) {
            if (radios[i].checked) {
                var checkedRadio = radios[i].value;
            }
        }

        // All cbox genres
        let genres = document.querySelectorAll(".cbox-genre");
        let checkedGenres = [];
        for (var i = 0; i < genres.length; i++) {
            if (genres[i].checked) {
                checkedGenres.push(genres[i].value)
            }
        }

        // Release Year
        let releaseFrom = document.getElementById('from')
        let releaseTo = document.getElementById('to')
        console.log(typeof(releaseFrom))
        let releaseYear = [releaseFrom.value, releaseTo.value]

        // AJAX code
        $.ajax({
            url: "/randomizer",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({
                status: checkedRadio,
                genres: checkedGenres,
                year: releaseYear
            }),
        })
    }
</script>
 <div class="tags">
    <form action="/randomizer" method="post">
        <div class="tag" id="movieStatus-tag">
            <div class="header">Watched or not</div>
            <div class="body">
                <!-- Allow only one to be checked -->
                <input type="radio" id="all" name="radio-seen" value="all">
                <label for="all">All Movies</label>
                <input type="radio" id="unseen" name="radio-seen" value="unseen">
                <label for="unseen">Unseen</label>
                <input type="radio" id="seen" name="radio-seen" value="seen">
                <label for="seen">Seen</label>
            </div>
        </div>
        <div class="tag" id="genre-tag">
            <div class="header">Genres</div>
            <div class="body">
                <li>
                    <input type="checkbox" id="all-genres" class="cbox-genre" name="cbox-all-genres" value="All Genres" onclick="genreChecked(this)">
                    <label for="all-genres">All Genres</label>
                </li>
                {% for genre in genres %}
                    <li>
                        <input type="checkbox" id="{{ genre }}" class="cbox-genre" name="cbox-genre" value="{{ genre }}" onclick="genreChecked(this)">
                        <label for="{{ genre }}">{{ genre }}</label>
                    </li>
                {% endfor %}
            </div>
        </div>
        <div class="tag" id="year-tag">
            <div class="header">Release Year</div>
            <div class="body">
                <!-- From, to. -->
                <input type="text" id="from" placeholder="From">
                <input type="text" id="to" placeholder="To">
            </div>
        </div>
        <div class="submit-tags">
            <input type="button" onclick="testing()"/>
        </div>
    </form>
 </div>
{% endblock %}
Asked By: Chris

||

Answers:

You can render different templates for both pages or you can render 1 template and have different parts for each request response.

Method 1 – Different templates

# GET request
if request.method == "GET":
    return render_template("randomizer1.html", genres=userGenres(session['user_id'])

# POST request
else:
    return render_template("randomizer2.html", movies = final_movies)

Method 2 – Same templates with different sections

# GET request
if request.method == "GET":
    context = {
      genres : userGenres(session['user_id'],
      section : 'get',
    }
    return render_template("randomizer1.html", context)

# POST request
else:
    context = {
      movies = final_movies,
      section : 'post',
    }
    return render_template("randomizer1.html", context)

In your templates you can load different sections using if condition like this…

{% block main %}
   {% if section == 'get %}
      'Your desired code for GET request page'
   {% elif section == 'post %}
      'Your desired code for POST request page'
   {% endif %}
{% endblock %}
Answered By: Usama Saeed
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.