Python Forum
Having trouble with passing variables
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Having trouble with passing variables
#1
Hey guys I'm SO close to being done with my project which is due in 9 days. I just need a few final touchups.

I am able to leave reviews on my site - even though it looks sloppy - it works.

However, one requirement is that the same username not be able to leave more than one review for each book. I have the username variable in my search method but I don't have it in my book method. I'm kind of having a brain fart on what to do can someone help me jog my memory on how I pass username from search to book if it's not in the url? If I can get the username onto the book page, then I'm set. But right now I tried a few methods but it's just coming up as empty [] once I get to the book page.

I know there's a way to use sessions but it might take too long to go back now. I just need to do this the sloppy way I think.

Please check out my code and give me some ideas of how I should attack this. Thanks a lot guys.

@app.route("/search", methods=["GET", "POST"])
def search():
    username = request.form.get("username")
    search = request.form.get("search")
    searchCombo = search + '%'
    result = db.execute("SELECT * FROM books WHERE author LIKE :search OR isbn LIKE :search OR title LIKE :search LIMIT 20", {'search': searchCombo}).fetchall()
    return render_template("search.html", search=result, username=username)


@app.route("/book", methods=["GET", "POST"])
@app.route("/book/<isbn>")
def book(isbn = None):
    search = db.execute("SELECT * FROM books WHERE isbn = :isbn", {'isbn':isbn}).fetchone()
    isbn = search[0]
    title =  search[1]
    author = search[2]
    year = search[3]
    ratingNum = ratingAvg = db.execute("SELECT COUNT(rating) FROM reviews WHERE isbn = :isbn", {'isbn':isbn}).fetchone()
    ratingAvg = db.execute("SELECT AVG(rating) FROM reviews WHERE isbn = :isbn", {'isbn':isbn}).fetchone()
    rating = db.execute("SELECT rating FROM reviews WHERE isbn = :isbn", {'isbn':isbn}).fetchone()
    reviews = db.execute("SELECT review FROM reviews WHERE isbn = :isbn", {'isbn':isbn}).fetchall()
    username = db.execute("SELECT username FROM reviews WHERE isbn = :isbn", {'isbn':isbn}).fetchall()
    review = reviews
    return render_template("book.html", title=title, author=author, year=year, reviews=reviews, isbn=isbn, username=username, rating=rating, ratingAvg=ratingAvg, ratingNum=ratingNum)

@app.route("/review", methods=["GET", "POST"])
def review():
    isbn = request.form.get("isbn")
    username = request.form.get("username")
    review = request.form.get("review")
    rating = request.form.get("rating")
    print(username)
    if rating and review:
        db.execute("INSERT INTO reviews (isbn, username, review, rating) VALUES (:isbn, :username, :review, :rating)", {"isbn":isbn, "username":username, "review":review, "rating":rating})
        db.commit()
        return render_template("review.html")
    else:
        return render_template("404.html")
search.html :
<!DOCTYPE html>
<html>
  <head>
    <title>Search Bookstore</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
  </head>
  <body>
    <div class="container">
      <p class="login">Logged in as <b> {{username}}</b>. <a href="register">Log out</a></p>
      
       <div class="topnav">
        
        <form
       name="frmInfo3"
       action="/search"
       method="post"     >
  
  <input type="text" size=50% placeholder="Search Books by ISBN, Title, or Author" id="search" name="search">
  <input type="text" placeholder={{username}} id="username" name="username" value={{username}}>
  <input type="submit" id="search" value="search" />
  </form>
        <ul id="results">
          {% for i in search %}
            <li>
            <a href="book/{{i[0]}}">{{i}}</li></a>
            
          {% endfor %}
      
        </ul>
</div> 
      
    </div>
        </form>
  </body>
</html>
book.html:

!DOCTYPE html>
<html>
  <head>
    <title>{{isbnResult}}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
  </head>
  <body>
     
  <h1>{{title}}</h1>
  <p>By: {{author}}</p>
  <p>{{year}}</p>
  <p>ISBN: {{isbn}}</p>
  <p>Number of ratings: {{ratingNum}}</p>
  <p>Goodreads Average rating: </p>
  <p>Goodreads # of Reviews: </p>
  <p>Our Average rating: {{ratingAvg}}</p>
  <p>Our # of Reviews: </p>
  <ul id="reviews">
          {% for i in reviews %}
          
            <li>{{i}}</li>
            
       
          {% endfor %}
        <p></p>
        </ul>
   <form
       name="frmInfo4"
       action="/review"
       method="post"     >
    
    <input type="text" id=isbn name=isbn value={{isbn}} size=1>
    <input type="text" id=username name=username value={{username}} size=1>

  <input type="text" id="reviews" name="review" placeholder="Leave a Review">
  <select id="rating" name="rating">
    <option value=1>1</option>
    <option value=2>2</option>
    <option value=3>3</option>
    <option value=4>4</option>
    <option value=5>5</option>
  </select>
  <input type="submit" id="review" value="Submit Review" />
  </form>
  </body>
</html>
Review.html :

<!DOCTYPE html>
<html>
  <head>
    <title>{{isbnResult}}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
  </head>
  <body>
     
  <h1>review submitted!</h1>
  </body>
</html>
Reply
#2
Why do you need the username on the search page anyway? That seems odd. Surely they only need to fill it in when they're submitting a review and at that point, you do the check?
Reply
#3
Well I don't NEED to but I have it so when you're logged in it says "Logged in as: " {{username}}

But even so how can I check when I submit the review? I can't do that either without getting the variable into the book method.

Having it in search isn't so important but it doesn't hurt - and if I can get it in search I should be able to get it in book too right? Any ideas without creating a whole new login structure?
Reply
#4
It doesn't seem like you have real login functionality in your app, just you're passing the username in your search form and then you just put it back on the page. Remember that HTTP requests are independent, so if you need state (like the logged in user in this case) that's carried over across requests, you need to manage that somehow (see, e.g. Flask-Login).

I guess if you aren't going to add login functionality, then I guess the username field in the review form is the way to do it. I don't know what your assignment requirements regarding login are, so I don't know whether you need to invest time in that.
Reply
#5
No It doesn't say that I have to create a fully functioning log in. Just an ability to login in with password and log back out which I do by sending them back to the front page.

I looked at the flask login and it seems like too much to learn. I'm on the final stretch after working on this for 8 weeks and my app is pathetic but at least it works.

What should I do to get the username? Please guide me somewhere! I'm lost. Thanks

OK never mind that. I just included another form for the user to use their username and password in order to leave a comment. So that solves that.

Now what I have to do is make it so that the user cannot leave a comment for the same book twice. I am picturing this in my head but -again - i'm pretty slow - so can you help me visualize how to do this?

Thanks

Nevermind! I figured that out as well! I simply wrote a db.execute SQL script searching the Reviews table for isbn and username exact matches. If there is one, I don't allow the review to be published.

I'm almost there!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020