-1

I've been searching all over for a resolution but can't find the cause. I have an html form that posts to an endpoint in flask but for some reason the function in the route is passing nothing into the variables needed to add to the database.

error message

add_classified(title, price, location, description)
TypeError: add_classified() takes 0 positional arguments but 4 were given

Any help would be greatly appreciated

Code

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

app = Flask(__name__)

def get_classifieds():
    conn = sqlite3.connect("classifieds.db")
    c = conn.cursor()
    c.execute("SELECT \* FROM classifieds")
    classifieds = c.fetchall()
    conn.close()
    return classifieds

def add_classified(title, price, location, description):
    conn = sqlite3.connect("classifieds.db")
    c = conn.cursor()
    c.execute("INSERT INTO classifieds (title, price, location, description) VALUES (?, ?, ?, ?)", (title, price, location, description))
    conn.commit()
    conn.close()

@app.route("/")
def index():
    classifieds = get_classifieds()
    return render_template("index.html", classifieds=classifieds)

@app.route("/classified/\<int:id\>")
def classified_detail(id):
    conn = sqlite3.connect("classifieds.db")
    c = conn.cursor()
    c.execute("SELECT \* FROM classifieds WHERE id=?", (id,))
    classified = c.fetchone()
    conn.close()
    return render_template("classified_detail.html", classified=classified)

@app.route("/add", methods=\["GET", "POST"\])
def add_classified():
    if request.method == "POST":
        \# Get form data
        title = request.form\["title"\]
        price = request.form\["price"\]
        location = request.form\["location"\]
        description = request.form\["description"\]

        # Add classified to database
        add_classified(title, price, location, description)
    
        return redirect(url_for("index"))

    else:
        return render_template("add_classified.html")

if __name__ == "__main__":
    app.run()

tried adding the variables (title, price, location, description) to the function like so:

@app.route("/add", methods=["GET", "POST"])def add_classified(title, price, location, description):if request.method == "POST":# Get form datatitle = request.args.get('title')price = request.args.get('price')location = request.args.get('location')description = request.args.get('description')
    # Add classified to database
    add_classified(title, price, location, description)

    return redirect(url_for("index"))
else:
    return render_template("add_classified.html")


if __name__ == "__main__":
app.run()

html form in (classified.html)

    <form method="post" action="{{ url_for('add_classified') }}">
      <label for="title">Title:</label><br>
      <input type="text" id="title" name="title"><br>
      <label for="price">Price:</label><br>
      <input type="text" id="price" name="price"><br>
      <label for="location">Location:</label><br>
      <input type="text" id="location" name="location"><br>
      <label for="description">Description:</label><br>
      <textarea id="description" name="description"></textarea><br><br>
      <input type="submit" value="Submit">
    </form> 
davidism
  • 121,510
  • 29
  • 395
  • 339
  • 2
    The error said the opposite - your `add_classified` function expects no parameters at all. So the error doesn't correspond the code you sent, putting aside very weirds formatting. – kosciej16 Dec 31 '22 at 10:24
  • 1
    Fix the indentation of the shown code. – Michael Butscher Dec 31 '22 at 10:28
  • it's not the indentation, it just showed up that way in the post – devzone777 Dec 31 '22 at 10:35
  • as noted above I did try adding the variables into @app.route("/add"... which produced a different error with the opposite complaint: "return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) TypeError: add_classified() missing 4 required positional arguments: 'title', 'price', 'location', and 'description' " – devzone777 Dec 31 '22 at 10:44
  • So without the params added to the function in the route it says the arguments are there but the function isn't asking for them. But if I put the params in there it then says that the arguments are missing – devzone777 Dec 31 '22 at 10:53
  • The problem is that your url definition for the route has to match the function definition for the route. See [this post](https://stackoverflow.com/q/7478366/15368978) for more info and examples of how to fix this issue. – Patrick Yoder Dec 31 '22 at 11:04

1 Answers1

0

Change the name of the route to something different, you have a recursive call inside your function (you're not calling the add_classified you think you're calling)

change the route from

@app.route("/add", methods=\["GET", "POST"\])
def add_classified()

to

@app.route("/add", methods=\["GET", "POST"\])
def add_classified_handler()

This is the problem:

@app.route("/add", methods=\["GET", "POST"\])
def add_classified():
        ...
    # this calls the route function
    add_classified(title, price, location, description)
Moad Ennagi
  • 1,058
  • 1
  • 11
  • 19
  • Thanks @moad I did what you suggested but got a new error: Could not build url for endpoint 'add_classified'. Did you mean 'add_classified_handler' instead? – devzone777 Dec 31 '22 at 11:23
  • you would have to change (in the html form) the action="{{ url_for('add_classified') }}" to action="{{ url_for('add_classified_handler') }}" because the function does not have the same name now – Moad Ennagi Dec 31 '22 at 11:27
  • Thanks, that made progress. Now a new error but I'll try to resolve – devzone777 Dec 31 '22 at 11:32