Forums

Why does my approach of return redirect which calls a seperate Classfully method that returns render_template work for function A but not function B?

So In my project I am trying to do this basic idea:

  1. return redirect from AJAX POST Function A to "songU"
  2. "songU" returns render_template("songsLoaded.html") which calls AJAX POST Request B ideally

This method works to transition from adding a user's artists to the db to the songs. The songs will be added to the database however it does not return the desired template when I try this approach with "songU". I have tried even returning my index template in songU and that still didnt redirect which leads me to believe it is not an issue with my template. I do not appear to be getting any errors in my access log and do not in my error log. I have included my access log at the bottom. As you can see artistU will get called successfully and redirect to addSong but nothing happens after songU is called successfully

Am I doing something wrong? Are there better ways to go about this? Any suggestions are greatly appreciated

This question was also asked on stackO at: https://stackoverflow.com/questions/67386176/why-does-my-approach-of-return-redirect-which-calls-a-seperate-classfully-method

This is a Flask-Classful class in a PythonAnywhere program. The class name is DBFunctions

Class setup:

class DBFunctions(FlaskView):
    default_methods = ['GET', 'POST']

addSong function:

def addSong(self):
    pass
    # START TIMER FOR FUNCTION
    # startTime = time.perf_counter();

    global songDict
    global halfSList
    global finalSList
    global albumDict
    try:
        sessionUser = dbSession.query(User).filter_by(username=session['username']).scalar()
    except:
        dbSession.rollback()
        sessionUser = dbSession.query(User).filter_by(username=session['username']).scalar()

    for i in range(0, len(finalSList)):
        # IF TIMER NOT EQUAL TO 290, call addSongFun with startingIndex
        songName = finalSList[i][0]
        artistName = finalSList[i][1][0]
        tP = finalSList[i][1][1]
        tC = finalSList[i][1][2]
        songResponse = list(json.loads(getSong(artistName, songName)))
        albumName = str(songResponse[0])
        uri = songResponse[1]
        if albumName not in albumDict.keys():
            albumDict.update({albumName: [artistName, int(tP), int(tC), uri]})
        else:
            albumDict[albumName][1] += int(tP)
            albumDict[albumName][2] += int(tC)
        createdSong = Song(trackName = songName, artist = artistName, albumName = albumName, time_played = tP, clicks = tC, song_uri=uri)
        sessionUser.songLibrary.append(createdSong)
        try:
            dbSession.commit()
        except:
            dbSession.rollback()
            dbSession.commit()
    return redirect(url_for('DBFunctions:songU'))

Song redirector function:

def songU(self):
    pass
    return render_template("songsLoaded.html")

Desired template: (uncommenting out the addAlbum request doesn't add songs to the db, but I think this problem gets fixed with proper redirection)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Song Uploaded</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles/styles.css') }}">
    <script type = "text/javascript" src = "{{ url_for('static',filename='js/main.js') }}" ></script>
</head>
<body style="background-color:black;">
<div class="topnav" align="center">
    <a><img src = "{{ url_for('static',filename='spotifyIcon') }}" height="20" width="20"></a>
    <a style="height: 23px" href="#home" onclick="home()">Home</a>
    <a href="#instructions" onclick="instructions()">Instructions</a>
    <a id="uf" class="active" href="#upload" onclick="uploadF()">Login / Register</a>
    <a href="#basic" onclick="basicInfo()">Basic Info</a>
    <a href="#artist" onclick="artistInfo()">Artist Data</a>
    <a href="#song" onclick="songInfo()">Song Data</a>
    <a href="#album" onclick="albumInfo()">Album Data</a>
    <a href="#playlist" onclick="playlistInfo()">Playlist Data</a>
    <a href="#listening" onclick="dayInfo()">Listening Data</a>
    <a href="#plot" onclick="plot()">Data Plots</a>
    <a href="#search" onclick="searchFun()">Search</a>
    <a href="#feedback" onclick="feedback()">Submit Feedback</a>
    <a href="#about" onclick="about()">About</a>
    <a href="#share" onclick="share()">Share</a>
</div>
<h1 id="headerText" align="center">Your song data has been uploaded to the server. Your albums are currently being added</h1>
<script>
    /*
    let loaderIcon = document.createElement("div");
    loaderIcon.setAttribute("class", "loader");

    document.body.appendChild(loaderIcon);
    var request = $.ajax({
        url: "https://spotify365.pythonanywhere.com/addAlbum",
        type: 'POST'
    });
    */
</script>
</body>
</html>

Access log:

24.154.122.253 - - [04/May/2021:13:08:09 +0000] "POST /uploadFile HTTP/1.1" 308 305 "https://spotify365.pythonanywhere.com/upload/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" "24.154.122.253" response-time=0.064
24.154.122.253 - - [04/May/2021:13:08:22 +0000] "POST /uploadFile/ HTTP/1.1" 302 225 "https://spotify365.pythonanywhere.com/upload/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" "24.154.122.253" response-time=9.080
24.154.122.253 - - [04/May/2021:13:08:22 +0000] "GET /artistU/ HTTP/1.1" 200 815 "https://spotify365.pythonanywhere.com/upload/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" "24.154.122.253" response-time=0.041
24.154.122.253 - - [04/May/2021:13:08:22 +0000] "POST /addSong HTTP/1.1" 308 299 "https://spotify365.pythonanywhere.com/artistU/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" "24.154.122.253" response-time=0.004
24.154.122.253 - - [04/May/2021:13:08:42 +0000] "POST /addSong/ HTTP/1.1" 302 221 "https://spotify365.pythonanywhere.com/artistU/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" "24.154.122.253" response-time=20.279
24.154.122.253 - - [04/May/2021:13:08:42 +0000] "GET /songU/ HTTP/1.1" 200 672 "https://spotify365.pythonanywhere.com/artistU/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" "24.154.122.253" response-time=0.002

I'm a bit confused -- what do you expect to happen after the request to /songU/? What gets displayed in the browser?

@giles

I am trying to return a render_template from both uploadFile and addSong. I was having trouble simply using just render_template so I tried redirecting to a different endpoint which in turn would call render_template sperately but that still doesnt actually return songsUploaded even though the songs are added to the db. The HTML page remains on my artistUploaded.html

Are there better ways to go about this?

I have since tried adding static endpoints to my server and tried directly calling redirect from addSong like so:

return redirect("https://spotify365.pythonanywhere.com/static/songsLoaded.html")

but this still does not return the template and it also doesnt add the songs to the DB

The only thing I can suggest is that you add some logging to your views (prints to stderr will appear in your error log). Then you can perhaps use the logged information to determine what your code is doing and why. Then perhaps you can work out why it's not behaving the way you expect.