skip to Main Content

I’ve already seen this question, but my code still doesn’t work. I have 3 files (main.py and add.html are important here).

The user enters book name, author and rating (in ‘/add’), and the given values should be passed to main.py and printed out. But it gives me an 400 error, even thou I gave the needed values in add.html and in main.py.

Can someone help me find what’s wrong?

Thanks.

main.py

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

all_books = []


@app.route('/')
def home():
  return render_template('index.html')


@app.route('/add', methods=['GET', 'POST'])
def add():
  book_name = request.form['bookName']
  book_author = request.form['book-author']
  book_rating = request.form['book-rating']
  return f"<h1>Name: {book_name}, Author: {book_author}, Rating: {book_rating}</h1>"


if __name__ == "__main__":
  app.run(host='0.0.0.0', debug=True)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Library</title>
</head>
<body>
<h1>My Library</h1>
    <ul>
        <li></li>
    </ul>
    
<a href="{{ url_for('add') }}">Add New Book</a>
</body>
</html>

add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Add Book</title>
</head>
<body>
  <form action="/add" method="post">
    <label>Book Name</label>
    <input type="text" id="bookName" name="book-name">
    <label>Book Author</label>
    <input type="text" id="book-author" name="book-author">
    <label>Rating</label>
    <input type="text" id="book-rating" name="book-rating">
    <button type="submit">Add Book</button>
  </form>
</body>
</html>

2

Answers


  1. Chosen as BEST ANSWER

    So I found out a solution to the problem without adding a new route as @Marijn did. I changed the route in index.html to be dynamic. Here is the code for main.py and add.html:

    I also changed the part where instead of printing it out it adds it as a dictionary to a list (this doesn't have anything to do with the question so don't mind that part).

    main.py

    from flask import Flask, render_template, request, redirect, url_for
    
    app = Flask(__name__)
    
    all_books = []
    
    
    @app.route('/')
    def home():
        return render_template("index.html", books=all_books)
    
    
    @app.route("/add", methods=["GET", "POST"])
    def add():
        if request.method == "POST":
            new_book = {
                "title": request.form["title"],
                "author": request.form["author"],
                "rating": request.form["rating"]
            }
            all_books.append(new_book)
        return render_template("add.html")
    
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', debug=True)
    

    add.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Add Book</title>
    </head>
    <body>
        <form action="{{ url_for('add') }}" method="POST">
            <label>Book Name</label>
            <input name="title" type="text">
            <label>Book Author</label>
            <input name="author" type="text">
            <label>Rating</label>
            <input name="rating" type="text">
            <button type="submit">Add Book</button>
        </form>
    </body>
    </html>
    

  2. The problem is that you try to use the /add route for two things, first trying to display the add.html page and second processing the form on that page. You need to separate these two by creating a separate route for displaying the page.

    Code:

    @app.route('/add')
    def add():
      return render_template('add.html')
    
    @app.route('/added', methods=['GET', 'POST'])
    def added():
      book_name = request.form['book-name']
      book_author = request.form['book-author']
      book_rating = request.form['book-rating']
      return f"<h1>Name: {book_name}, Author: {book_author}, Rating: {book_rating}</h1>"
    

    Now call /added from the form in add.html:

    <form action="/added" method="POST">
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search