1

I 'ld like for a user to drop a random search in a search form for a book title and find get results if the book is in the db. Below is part of the code block. I 'm having some issues searching for a single document in my mongodb using a search field and search strings. Below is the code. I'm trying to get the search result via the find_book route. The code above with the /find_book/<book_id> returns errors. Below is a part of my code in the app.py file and the search form. I get the following errors. werkzeug.routing.BuildError werkzeug.routing.BuildError: Could not build url for endpoint 'find_book'. Did you forget to specify values ['book_title']? Traceback (most recent call last)

  # create an instance of py_mongo with app as argument
mongo = PyMongo(app)


    @app.route('/')
    def home():
        return render_template('home.html')
    
    
    # define the various menu options
    @app.route('/get_books')
    def get_books():
        return render_template('books.html', books=mongo.db.books.find())
    
    
    # Add a book
    @app.route('/add_book')
    def add_book():
        return render_template('add_book.html',
                               faculties=mongo.db.faculties.find())
    
    
    # Add submit button for Books
    @app.route('/insert_book', methods=['POST'])
    def insert_book():
        book = mongo.db.books
        book.insert_one(request.form.to_dict())
        return redirect(url_for('get_books'))
    
    
    # wire the edit button
    @app.route('/edit_book/<book_id>')
    # description task, name, due date, is urgent fields will be
    # pre-populated based on the information returned in the task.
    def edit_book(book_id):
        a_book = mongo.db.books.find_one({"_id": ObjectId(book_id)})
        # category names will be prepolulated based on the collection
        # # of categories returned in the categories cursor
        all_faculties = mongo.db.faculties.find()
        return render_template('edit_book.html',
                               book=a_book, faculties=all_faculties)
    
    
    @app.route('/update_book/<book_id>', methods=['POST'])
    def update_book(book_id):
        # access the database collection
        book = mongo.db.books
        # call the update function, specify an id
        book.update({'_id': ObjectId(book_id)},
        {
            'faculty_name': request.form.get('faculty_name'),
            'subject_name': request.form.get('subject_name'),
            'book_title': request.form.get('book_title'),
            'book_author': request.form.get('book_author'),
            'book_description': request.form.get('task_description'),
            'lender_name': request.form.get('lender_name'),
            'due_date': request.form.get('due_date'),
            'is_available': request.form.get('is_urgent')
        })
        return redirect(url_for('get_books'))
    # specify the form fields to match the keys on the task collection
    
    
    # delete a book
    @app.route('/delete_book/<book_id>')
    def delete_book(book_id):
        mongo.db.books.remove({'_id': ObjectId(book_id)})
        return redirect(url_for('get_books'))
    
    
    # find a book by text search
    @app.route('/find_book/<book_title>', methods=['GET'])
    def find_book(book_title):
        book_title = mongo.db.books
        book_title.find_one(
        {
            'book_title': request.form.get('book_title'),
        })
        return render_template('find.html', book_title=book_title)
    
    
    # categories function
    @app.route('/get_faculties')
    def get_faculties():
        return render_template('faculties.html',
                               faculties=mongo.db.faculties.find())
    
    
    if __name__ == '__main__':
        app.run(host=os.environ.get('IP'),
                port=int(os.environ.get('PORT')),
                debug=True)



<form action="{{ url_for('find_book') }}" method="GET">
  <input type="text" placeholder="Book Title" id="book_title" name="book_title" >
  <button type="submit"><i class="fa fa-search">Search</i></button>
</form>
new_user
  • 11
  • 1

1 Answers1

0

Your find_book route is expecting an argument book_title

But you are not passing that in {{ url_for('find_book') }}

You could just change this route to @app.route('/find_book') and get the value from request.form or if you are using this route in another place of your application you could use the approach from this question and use this way:

@app.route('/find_book/', defaults={'book_title': None})
@app.route('/find_book/<book_title>')
def find_book(book_title):
    books = mongo.db.books
    if book_title is None:
        book_title = request.form.get('book_title')
    book = books.find_one({
        'book_title': book_title
    })
    return render_template('find.html', book=book)

I could not run this snippet of code now, so let me know if dont work.

wiltonsr
  • 639
  • 5
  • 16
  • I'm getting some results. But the find_one() only displays the first item in my collection which is not necessarily the result. An example of a search i just did. However this is not the book I searched for. Subject Name Book Title Author Description Availability Name of Lender Due Date Marine Sciense Whales Mark Jones sr Secret song of whales Jane Doe 28 July, 2020 – new_user Jul 24 '20 at 02:12
  • This is the expected behavior from `find_one`. Try change to `find` to get a list of results or refine your search to use multiple parameters. – wiltonsr Jul 24 '20 at 12:07
  • Thank you so much for your help. You've really enabled me to carry on with this project. – new_user Jul 27 '20 at 08:47